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>
62 #include <sys/param.h>
64 static int send_to_cachemgr(const char *,
65 ns_ldap_attr_t
**, ns_ldap_error_t
**);
67 static int escape_str(char *, char *);
70 * If the rdn is a mapped attr:
71 * return NS_LDAP_SUCCESS and a new_dn.
72 * If no mapped attr is found in the rdn:
73 * return NS_LDAP_SUCCESS and *new_dn == NULL
76 * dn = cn=foo,dc=bar,dc=com
77 * attributeMapping: abc:cn=sn
79 * new_dn = sn=foo,dc=bar,dc=com
83 replace_mapped_attr_in_dn(
84 const char *service
, const char *dn
, char **new_dn
)
87 char **dnArray
= NULL
;
90 int len
= 0, orig_len
= 0, mapped_len
= 0;
96 * separate dn into individual componets
98 * "automountKey=user_01" , "automountMapName_test=auto_home", ...
100 dnArray
= ldap_explode_dn(dn
, 0);
101 if (!dnArray
|| !*dnArray
)
102 return (NS_LDAP_INVALID_PARAM
);
104 cur
= strchr(dnArray
[0], '=');
106 __s_api_free2dArray(dnArray
);
107 return (NS_LDAP_INVALID_PARAM
);
111 /* we only check schema mapping for automount, not for auto_* */
112 if (strncasecmp(service
, NS_LDAP_TYPE_AUTOMOUNT
,
113 sizeof (NS_LDAP_TYPE_AUTOMOUNT
) - 1) == 0)
114 rservice
= "automount";
116 rservice
= (char *)service
;
118 mappedattr
= __ns_ldap_getMappedAttributes(rservice
, dnArray
[0]);
119 if (!mappedattr
|| !mappedattr
[0]) {
120 __s_api_free2dArray(dnArray
);
122 __s_api_free2dArray(mappedattr
);
123 return (NS_LDAP_SUCCESS
);
125 orig_len
= strlen(dnArray
[0]);
128 * The new length is *dn length + (difference between
129 * orig attr and mapped attr) + 1 ;
131 * automountKey=aa,automountMapName=auto_home,dc=foo,dc=com
133 * cn=aa,automountMapName=auto_home,dc=foo,dc=com
135 mapped_len
= strlen(mappedattr
[0]);
137 len
= dn_len
- orig_len
+ mapped_len
+ 1;
138 *new_dn
= (char *)calloc(1, len
);
139 if (*new_dn
== NULL
) {
140 __s_api_free2dArray(dnArray
);
141 __s_api_free2dArray(mappedattr
);
142 return (NS_LDAP_MEMORY
);
145 (void) snprintf(*new_dn
, len
, "%s=%s", mappedattr
[0], dn
+ orig_len
+1);
146 __s_api_free2dArray(dnArray
);
147 __s_api_free2dArray(mappedattr
);
149 return (NS_LDAP_SUCCESS
);
154 * The following function is only used by the
155 * "gecos" 1 to N attribute mapping code. It expects
156 * and handle only one data/length pair.
167 struct berval
**bmodval
;
169 /* dup attribute name */
170 mod
->mod_type
= strdup(mtype
);
171 if (mod
->mod_type
== NULL
)
175 * assume single value,
176 * since only one value/length pair passed in
178 bmodval
= (struct berval
**)calloc(2, sizeof (struct berval
*));
179 if (bmodval
== NULL
) {
181 mod
->mod_type
= NULL
;
184 bmodval
[0] = (struct berval
*)calloc(1, sizeof (struct berval
));
185 if (bmodval
[0] == NULL
) {
187 mod
->mod_type
= NULL
;
192 /* set pointer to data */
193 bmodval
[0]->bv_val
= mvptr
;
196 bmodval
[0]->bv_len
= mvlen
;
199 * turn on the BVALUE bit to indicate
200 * that the length of data is supplied
202 mod
->mod_op
= mop
| LDAP_MOD_BVALUES
;
204 mod
->mod_bvalues
= bmodval
;
210 freeModList(LDAPMod
**mods
)
218 for (i
= 0; mods
[i
]; i
++) {
220 /* free attribute name */
222 if (mods
[i
]->mod_type
) {
223 if (strcasecmp(mods
[i
]->mod_type
, "objectclass") == 0)
225 free(mods
[i
]->mod_type
);
228 if (mods
[i
]->mod_bvalues
== NULL
)
231 * LDAP_MOD_BVALUES is only set by
232 * the "gecos" 1 to N attribute mapping
233 * code, and the attribute is single valued.
235 if (mods
[i
]->mod_op
& LDAP_MOD_BVALUES
) {
236 free(mods
[i
]->mod_bvalues
[0]);
240 * only values for the "objectclass"
241 * were dupped using strdup.
242 * other attribute values were
243 * not dupped, but via pointer
244 * assignment. So here the
245 * values for "objectclass"
246 * is freed one by one,
247 * but the values for other
248 * attributes need not be freed.
250 for (j
= 0; mods
[i
]->mod_values
[j
]; j
++)
251 free(mods
[i
]->mod_values
[j
]);
255 free(mods
[i
]->mod_bvalues
);
259 free((char *)(mods
[0]));
264 __s_api_makeModListCount(
266 const ns_ldap_attr_t
* const *attr
,
271 LDAPMod
**mods
, *modlist
;
277 char *c
, *comma1
= NULL
, *comma2
= NULL
;
278 int schema_mapping_existed
= FALSE
;
279 int auto_service
= FALSE
;
283 * add 2 for "gecos" 1 to up to 3 attribute mapping
285 mods
= (LDAPMod
**)calloc((count
+ 3), sizeof (LDAPMod
*));
290 * add 2 for "gecos" 1 to up to 3 attribute mapping
292 modlist
= (LDAPMod
*)calloc(count
+ 2, sizeof (LDAPMod
));
293 if (modlist
== NULL
) {
298 if (service
!= NULL
&& strncasecmp(service
, NS_LDAP_TYPE_AUTOMOUNT
,
299 sizeof (NS_LDAP_TYPE_AUTOMOUNT
) - 1) == 0)
303 * see if schema mapping existed for the given service
305 mapping
= __ns_ldap_getOrigAttribute(service
,
306 NS_HASH_SCHEMA_MAPPING_EXISTED
);
308 schema_mapping_existed
= TRUE
;
309 __s_api_free2dArray(mapping
);
313 for (i
= 0, k
= 0; k
< count
&& attr
[k
] != NULL
; i
++, k
++) {
314 mods
[i
] = &modlist
[i
];
315 mods
[i
]->mod_op
= mod_op
;
317 * Perform attribute mapping if necessary.
319 if (schema_mapping_existed
&& (flags
& NS_LDAP_NOMAP
) == 0) {
320 mapping
= __ns_ldap_getMappedAttributes(service
,
325 if (mapping
== NULL
&& auto_service
&&
326 (flags
& NS_LDAP_NOMAP
) == 0) {
328 * if service == auto_xxx and
329 * no mapped attribute is found
330 * and NS_LDAP_NOMAP is not set
331 * then try automount's mapped attribute
333 mapping
= __ns_ldap_getMappedAttributes("automount",
337 if (mapping
== NULL
) {
338 mods
[i
]->mod_type
= strdup(attr
[k
]->attrname
);
339 if (mods
[i
]->mod_type
== NULL
)
343 * 1 to N attribute mapping is only done for "gecos",
344 * and only 1 to 3 mapping.
347 * A. attrMap=passwd:gecos=a
348 * 1. gecos="xx,yy,zz" -> a="xx,yy,zz"
349 * 2. gecos="xx,yy" -> a="xx,yy"
350 * 3. gecos="xx" -> a="xx"
352 * B. attrMap=passwd:gecos=a b
353 * 4. gecos="xx,yy,zz" -> a="xx" b="yy,zz"
354 * 5. gecos="xx,yy" -> a="xx" b="yy"
355 * 6. gecos="xx" -> a="xx"
357 * C. attrMap=passwd:gecos=a b c
358 * 7. gecos="xx,yy,zz" -> a="xx" b="yy" c="zz"
359 * 8. gecos="xx,yy" -> a="xx" b="yy"
360 * 9. gecos="xx" -> a="xx"
362 * This can be grouped as:
364 * c1 cases: 1,2,3,6,9
365 * if ((attrMap=passwd:gecos=a) ||
366 * (no "," in gecos value))
367 * same as other no-mapping attributes,
368 * no special processing needed
372 * if ((attrMap=passwd:gecos=a b) ||
373 * (only one "," in gecos value))
380 * notes: in case c2 and c3, ... could still contain ","
382 if (strcasecmp(service
, "passwd") == 0 &&
383 strcasecmp(attr
[k
]->attrname
, "gecos") == 0 &&
384 mapping
[1] && attr
[k
]->attrvalue
[0] &&
385 (comma1
= strchr(attr
[k
]->attrvalue
[0],
386 COMMATOK
)) != NULL
) {
388 /* is there a second comma? */
389 if (*(comma1
+ 1) != '\0')
390 comma2
= strchr(comma1
+ 1, COMMATOK
);
393 * Process case c2 or c3.
394 * case c2: mapped to two attributes or just
397 if (mapping
[2] == NULL
|| comma2
== NULL
) {
401 * int mod structure for the first attribute
403 vlen
= comma1
- attr
[k
]->attrvalue
[0];
404 c
= attr
[k
]->attrvalue
[0];
407 rc
= init_bval_mod(mods
[i
], mod_op
,
408 mapping
[0], c
, vlen
);
412 /* don't leave a hole in mods array */
419 * init mod structure for the 2nd attribute
421 if (*(comma1
+ 1) == '\0') {
422 __s_api_free2dArray(mapping
);
428 mods
[i
] = &modlist
[i
];
431 * get pointer to data.
432 * Skip leading spaces.
434 for (c
= comma1
+ 1; *c
== SPACETOK
; c
++) {
438 /* get data length */
439 vlen
= strlen(attr
[k
]->attrvalue
[0]) -
440 (c
- attr
[k
]->attrvalue
[0]);
443 rc
= init_bval_mod(mods
[i
], mod_op
,
444 mapping
[1], c
, vlen
);
448 /* don't leave a hole in mods array */
453 /* done with the mapping array */
454 __s_api_free2dArray(mapping
);
462 * int mod structure for the first attribute
464 vlen
= comma1
- attr
[k
]->attrvalue
[0];
465 c
= attr
[k
]->attrvalue
[0];
468 rc
= init_bval_mod(mods
[i
], mod_op
,
469 mapping
[0], c
, vlen
);
473 /* don't leave a hole in mods array */
479 * init mod structure for the 2nd attribute
482 mods
[i
] = &modlist
[i
];
485 * get pointer to data.
486 * Skip leading spaces.
488 for (c
= comma1
+ 1; *c
== SPACETOK
; c
++) {
492 /* get data length */
496 rc
= init_bval_mod(mods
[i
], mod_op
,
497 mapping
[1], c
, vlen
);
501 /* don't leave a hole in mods array */
507 * init mod structure for the 3rd attribute
509 if (*(comma2
+ 1) == '\0') {
510 __s_api_free2dArray(mapping
);
516 mods
[i
] = &modlist
[i
];
518 * get pointer to data.
519 * Skip leading spaces.
521 for (c
= comma2
+ 1; *c
== SPACETOK
; c
++) {
525 /* get data length */
526 vlen
= strlen(attr
[k
]->attrvalue
[0]) -
527 (c
- attr
[k
]->attrvalue
[0]);
530 rc
= init_bval_mod(mods
[i
], mod_op
,
531 mapping
[2], c
, vlen
);
535 /* don't leave a hole in mods array */
540 /* done with the mapping array */
541 __s_api_free2dArray(mapping
);
549 mods
[i
]->mod_type
= strdup(mapping
[0]);
550 if (mods
[i
]->mod_type
== NULL
) {
553 __s_api_free2dArray(mapping
);
557 modval
= (char **)calloc(attr
[k
]->value_count
+1,
562 * Perform objectclass mapping.
563 * Note that the values for the "objectclass" attribute
564 * will be dupped using strdup. Values for other
565 * attributes will be referenced via pointer
568 if (strcasecmp(mods
[i
]->mod_type
, "objectclass") == 0) {
569 for (j
= 0; j
< attr
[k
]->value_count
; j
++) {
570 if (schema_mapping_existed
&&
571 (flags
& NS_LDAP_NOMAP
) == 0)
573 __ns_ldap_getMappedObjectClass(
574 service
, attr
[k
]->attrvalue
[j
]);
578 if (mapping
== NULL
&& auto_service
&&
579 (flags
& NS_LDAP_NOMAP
) == 0)
581 * if service == auto_xxx and
582 * no mapped objectclass is found
586 __ns_ldap_getMappedObjectClass(
587 "automount", attr
[k
]->attrvalue
[j
]);
589 if (mapping
&& mapping
[0]) {
590 /* assume single mapping */
591 modval
[j
] = strdup(mapping
[0]);
593 modval
[j
] = strdup(attr
[k
]->
596 if (modval
[j
] == NULL
)
600 for (j
= 0; j
< attr
[k
]->value_count
; j
++) {
601 /* ASSIGN NOT COPY */
602 modval
[j
] = attr
[k
]->attrvalue
[j
];
605 mods
[i
]->mod_values
= modval
;
613 __s_api_free2dArray(mapping
);
622 const ns_ldap_attr_t
* const *attr
,
626 ns_ldap_attr_t
**aptr
= (ns_ldap_attr_t
**)attr
;
632 /* count number of attributes */
636 return (__s_api_makeModListCount(service
, attr
, mod_op
, count
, flags
));
640 __s_cvt_freeEntryRdn(ns_ldap_entry_t
**entry
, char **rdn
)
642 if (*entry
!= NULL
) {
643 __ns_ldap_freeEntry(*entry
);
653 * This state machine performs one or more LDAP add/delete/modify
654 * operations to configured LDAP servers.
661 const ns_cred_t
*cred
,
663 ns_ldap_error_t
** errorp
)
665 ConnectionID connectionId
= -1;
666 Connection
*conp
= NULL
;
668 char *target_dn
= NULL
;
669 char errstr
[MAXERROR
];
670 int rc
= NS_LDAP_SUCCESS
;
671 int return_rc
= NS_LDAP_SUCCESS
;
672 int followRef
= FALSE
;
673 int target_dn_allocated
= FALSE
;
677 boolean_t from_get_lderrno
= B_FALSE
;
679 char *err
, *errmsg
= NULL
;
680 /* referrals returned by the LDAP operation */
681 char **referrals
= NULL
;
683 * list of referrals used by the state machine, built from
684 * the referrals variable above
686 ns_referral_info_t
*ref_list
= NULL
;
687 /* current referral */
688 ns_referral_info_t
*current_ref
= NULL
;
689 ns_write_state_t state
= W_INIT
, new_state
, err_state
= W_INIT
;
690 int do_not_fail_if_new_pwd_reqd
= 0;
691 ns_ldap_passwd_status_t pwd_status
= NS_PASSWD_GOOD
;
695 int nopasswd_acct_mgmt
= 0;
696 ns_conn_user_t
*conn_user
= NULL
;
701 /* return the MT connection and free the conn user */
702 if (conn_user
!= NULL
) {
703 if (conn_user
->use_mt_conn
== B_TRUE
) {
704 if (conn_user
->ns_error
!= NULL
) {
705 *errorp
= conn_user
->ns_error
;
706 conn_user
->ns_error
= NULL
;
707 return_rc
= conn_user
->ns_rc
;
709 if (conn_user
->conn_mt
!= NULL
)
710 __s_api_conn_mt_return(
713 __s_api_conn_user_free(conn_user
);
716 if (connectionId
> -1)
717 DropConnection(connectionId
, NS_LDAP_NEW_CONN
);
719 __s_api_deleteRefInfo(ref_list
);
720 if (target_dn
&& target_dn_allocated
)
724 /* see if need to follow referrals */
725 rc
= __s_api_toFollowReferrals(flags
,
727 if (rc
!= NS_LDAP_SUCCESS
) {
733 if (dn
[len
-1] == COMMATOK
)
734 rc
= __s_api_append_default_basedn(
735 dn
, &target_dn
, &target_dn_allocated
,
739 if (rc
!= NS_LDAP_SUCCESS
) {
744 new_state
= GET_CONNECTION
;
747 /* identify self as a write user */
748 conn_user
= __s_api_conn_user_init(NS_CONN_USER_WRITE
,
750 rc
= __s_api_getConnection(NULL
,
751 flags
, cred
, &connectionId
, &conp
, errorp
,
752 do_not_fail_if_new_pwd_reqd
, nopasswd_acct_mgmt
,
756 * If password control attached
758 * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO,
759 * free the error structure (we do not need
760 * the password management info).
761 * Reset rc to NS_LDAP_SUCCESS.
763 if (rc
== NS_LDAP_SUCCESS_WITH_INFO
) {
764 (void) __ns_ldap_freeError(errorp
);
766 rc
= NS_LDAP_SUCCESS
;
769 if (rc
!= NS_LDAP_SUCCESS
) {
775 new_state
= SELECT_OPERATION_ASYNC
;
777 new_state
= SELECT_OPERATION_SYNC
;
779 case SELECT_OPERATION_SYNC
:
780 if (ldap_op
== LDAP_REQ_ADD
)
781 new_state
= DO_ADD_SYNC
;
782 else if (ldap_op
== LDAP_REQ_DELETE
)
783 new_state
= DO_DELETE_SYNC
;
784 else if (ldap_op
== LDAP_REQ_MODIFY
)
785 new_state
= DO_MODIFY_SYNC
;
787 case SELECT_OPERATION_ASYNC
:
788 if (ldap_op
== LDAP_REQ_ADD
)
789 new_state
= DO_ADD_ASYNC
;
790 else if (ldap_op
== LDAP_REQ_DELETE
)
791 new_state
= DO_DELETE_ASYNC
;
792 else if (ldap_op
== LDAP_REQ_MODIFY
)
793 new_state
= DO_MODIFY_ASYNC
;
796 rc
= ldap_add_ext_s(conp
->ld
, target_dn
,
798 new_state
= GET_RESULT_SYNC
;
801 rc
= ldap_delete_ext_s(conp
->ld
, target_dn
,
803 new_state
= GET_RESULT_SYNC
;
806 rc
= ldap_modify_ext_s(conp
->ld
, target_dn
,
808 new_state
= GET_RESULT_SYNC
;
811 rc
= ldap_add_ext(conp
->ld
, target_dn
,
812 mods
, NULL
, NULL
, &msgid
);
813 new_state
= GET_RESULT_ASYNC
;
815 case DO_DELETE_ASYNC
:
816 rc
= ldap_delete_ext(conp
->ld
, target_dn
,
818 new_state
= GET_RESULT_ASYNC
;
820 case DO_MODIFY_ASYNC
:
821 rc
= ldap_modify_ext(conp
->ld
, target_dn
,
822 mods
, NULL
, NULL
, &msgid
);
823 new_state
= GET_RESULT_ASYNC
;
825 case GET_RESULT_SYNC
:
826 if (rc
!= LDAP_SUCCESS
) {
828 (void) ldap_get_lderrno(conp
->ld
,
832 * No need to deal with the error message if
833 * it's an empty string.
835 if (errmsg
!= NULL
&& *errmsg
== '\0')
838 if (errmsg
!= NULL
) {
840 * ldap_get_lderrno does not expect
841 * errmsg to be freed after use, while
842 * ldap_parse_result below does, so set
843 * a flag to indicate source.
845 from_get_lderrno
= B_TRUE
;
848 new_state
= W_LDAP_ERROR
;
850 return_rc
= NS_LDAP_SUCCESS
;
854 case GET_RESULT_ASYNC
:
855 rc
= ldap_result(conp
->ld
, msgid
, 1,
857 /* if no server response, set Errno */
859 (void) ldap_get_option(conp
->ld
,
860 LDAP_OPT_ERROR_NUMBER
, &Errno
);
861 new_state
= W_LDAP_ERROR
;
864 if (rc
== LDAP_RES_ADD
|| rc
== LDAP_RES_MODIFY
||
865 rc
== LDAP_RES_DELETE
) {
866 new_state
= PARSE_RESULT
;
875 * need Errno, referrals, error msg,
876 * and the last "1" is to free
879 rc
= ldap_parse_result(conp
->ld
, res
, &Errno
,
880 NULL
, &errmsg
, &referrals
, NULL
, 1);
882 * free errmsg if it is an empty string
884 if (errmsg
&& *errmsg
== '\0') {
885 ldap_memfree(errmsg
);
889 * If we received referral data, process
891 * - we are configured to follow referrals
892 * - and not already in referral mode (to keep
893 * consistency with search_state_machine()
894 * which follows 1 level of referrals only;
895 * see proc_result_referrals() and
896 * proc_search_references().
898 if (Errno
== LDAP_REFERRAL
&& followRef
&& !ref_list
) {
899 for (i
= 0; referrals
[i
] != NULL
; i
++) {
900 /* add to referral list */
901 rc
= __s_api_addRefInfo(&ref_list
,
902 referrals
[i
], NULL
, NULL
, NULL
,
904 if (rc
!= NS_LDAP_SUCCESS
) {
905 __s_api_deleteRefInfo(ref_list
);
910 ldap_value_free(referrals
);
911 if (ref_list
== NULL
) {
912 if (rc
!= NS_LDAP_MEMORY
)
913 rc
= NS_LDAP_INTERNAL
;
917 new_state
= GET_REFERRAL_CONNECTION
;
918 current_ref
= ref_list
;
921 ldap_memfree(errmsg
);
926 if (Errno
!= LDAP_SUCCESS
) {
927 new_state
= W_LDAP_ERROR
;
929 return_rc
= NS_LDAP_SUCCESS
;
933 case GET_REFERRAL_CONNECTION
:
935 * since we are starting over,
936 * discard the old error info
938 return_rc
= NS_LDAP_SUCCESS
;
940 (void) __ns_ldap_freeError(errorp
);
941 if (connectionId
> -1)
942 DropConnection(connectionId
, NS_LDAP_NEW_CONN
);
944 /* set it up to use a referral connection */
945 if (conn_user
!= NULL
) {
947 * If an MT connection is being used,
948 * return it to the pool.
950 if (conn_user
->conn_mt
!= NULL
)
951 __s_api_conn_mt_return(conn_user
);
953 conn_user
->referral
= B_TRUE
;
955 rc
= __s_api_getConnection(current_ref
->refHost
,
956 0, cred
, &connectionId
, &conp
, errorp
,
957 do_not_fail_if_new_pwd_reqd
,
958 nopasswd_acct_mgmt
, conn_user
);
961 * If password control attached
963 * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO,
964 * free the error structure (we do not need
965 * the password management info).
966 * Reset rc to NS_LDAP_SUCCESS.
968 if (rc
== NS_LDAP_SUCCESS_WITH_INFO
) {
969 (void) __ns_ldap_freeError(errorp
);
971 rc
= NS_LDAP_SUCCESS
;
974 if (rc
!= NS_LDAP_SUCCESS
) {
977 * If current referral is not
978 * available for some reason,
979 * try next referral in the list.
980 * Get LDAP error code from errorp.
982 if (*errorp
!= NULL
) {
983 ns_write_state_t get_ref
=
984 GET_REFERRAL_CONNECTION
;
986 ldap_error
= (*errorp
)->status
;
987 if (ldap_error
== LDAP_BUSY
||
988 ldap_error
== LDAP_UNAVAILABLE
||
990 LDAP_UNWILLING_TO_PERFORM
||
991 ldap_error
== LDAP_CONNECT_ERROR
||
992 ldap_error
== LDAP_SERVER_DOWN
) {
993 current_ref
= current_ref
->next
;
994 if (current_ref
== NULL
) {
995 /* no more referral to follow */
1000 * free errorp before going to
1003 (void) __ns_ldap_freeError(
1009 * free errorp before going to W_ERROR
1011 (void) __ns_ldap_freeError(errorp
);
1015 __s_api_deleteRefInfo(ref_list
);
1017 new_state
= W_ERROR
;
1018 if (conn_user
!= NULL
)
1019 conn_user
->referral
= B_FALSE
;
1022 /* target DN may changed due to referrals */
1023 if (current_ref
->refDN
) {
1024 if (target_dn
&& target_dn_allocated
) {
1027 target_dn_allocated
= FALSE
;
1029 target_dn
= current_ref
->refDN
;
1031 new_state
= SELECT_OPERATION_SYNC
;
1035 * map error code and error message
1036 * to password status if necessary.
1037 * This is to see if password updates
1038 * failed due to password policy or
1039 * password syntax checking.
1043 * check if server supports
1044 * password management
1047 __s_api_contain_passwd_control_oid(
1051 __s_api_set_passwd_status(
1054 * free only if not returned by ldap_get_lderrno
1056 if (!from_get_lderrno
)
1057 ldap_memfree(errmsg
);
1059 from_get_lderrno
= B_FALSE
;
1062 (void) snprintf(errstr
, sizeof (errstr
),
1063 "%s", ldap_err2string(Errno
));
1064 err
= strdup(errstr
);
1065 if (pwd_status
!= NS_PASSWD_GOOD
) {
1066 MKERROR_PWD_MGMT(*errorp
, Errno
, err
,
1069 MKERROR(LOG_INFO
, *errorp
, Errno
, err
, 0);
1071 if (conn_user
!= NULL
&&
1072 (Errno
== LDAP_SERVER_DOWN
||
1073 Errno
== LDAP_CONNECT_ERROR
)) {
1074 __s_api_conn_mt_close(conn_user
, Errno
, errorp
);
1076 return_rc
= NS_LDAP_INTERNAL
;
1081 (void) sprintf(errstr
,
1082 gettext("Internal write State machine exit"
1083 " (state = %d, rc = %d)."),
1084 err_state
, return_rc
);
1085 err
= strdup(errstr
);
1086 MKERROR(LOG_WARNING
, *errorp
, return_rc
, err
, 0);
1091 if (new_state
== W_ERROR
)
1094 if (conn_user
!= NULL
&& conn_user
->bad_mt_conn
== B_TRUE
) {
1095 __s_api_conn_mt_close(conn_user
, 0, NULL
);
1103 * should never be here, the next line is to eliminating
1106 return (NS_LDAP_INTERNAL
);
1113 const char *service
,
1115 const ns_ldap_attr_t
* const *attr
,
1116 const ns_cred_t
*cred
,
1118 ns_ldap_error_t
** errorp
)
1124 (void) fprintf(stderr
, "__ns_ldap_addAttr START\n");
1129 if ((attr
== NULL
) || (*attr
== NULL
) ||
1130 (dn
== NULL
) || (cred
== NULL
))
1131 return (NS_LDAP_INVALID_PARAM
);
1133 mods
= __s_api_makeModList(service
, attr
, LDAP_MOD_ADD
, flags
);
1135 return (NS_LDAP_MEMORY
);
1138 rc
= write_state_machine(LDAP_REQ_MODIFY
,
1139 (char *)dn
, mods
, cred
, flags
, errorp
);
1149 const char *service
,
1151 const ns_ldap_attr_t
* const *attr
,
1152 const ns_cred_t
*cred
,
1154 ns_ldap_error_t
** errorp
)
1160 (void) fprintf(stderr
, "__ns_ldap_delAttr START\n");
1165 if ((attr
== NULL
) || (*attr
== NULL
) ||
1166 (dn
== NULL
) || (cred
== NULL
))
1167 return (NS_LDAP_INVALID_PARAM
);
1169 mods
= __s_api_makeModList(service
, attr
, LDAP_MOD_DELETE
, flags
);
1171 return (NS_LDAP_MEMORY
);
1174 rc
= write_state_machine(LDAP_REQ_MODIFY
,
1175 (char *)dn
, mods
, cred
, flags
, errorp
);
1181 /* Retrieve the admin bind password from the configuration, if allowed. */
1183 get_admin_passwd(ns_cred_t
*cred
, ns_ldap_error_t
**errorp
)
1185 void **paramVal
= NULL
;
1187 char *modparamVal
= NULL
;
1190 * For GSSAPI/Kerberos, host credential is used, no need to get
1191 * admin bind password
1193 if (cred
->auth
.saslmech
== NS_LDAP_SASL_GSSAPI
)
1194 return (NS_LDAP_SUCCESS
);
1197 * Retrieve admin bind password.
1198 * The admin bind password is available
1199 * only in the ldap_cachemgr process as
1200 * they are not exposed outside of that
1204 if ((ldaprc
= __ns_ldap_getParam(NS_LDAP_ADMIN_BINDPASSWD_P
,
1205 ¶mVal
, errorp
)) != NS_LDAP_SUCCESS
)
1207 if (paramVal
== NULL
|| *paramVal
== NULL
) {
1208 rc
= NS_LDAP_CONFIG
;
1209 *errorp
= __s_api_make_error(NS_CONFIG_NODEFAULT
,
1210 gettext("Admin bind password not configured"));
1211 if (*errorp
== NULL
)
1212 rc
= NS_LDAP_MEMORY
;
1215 modparamVal
= dvalue((char *)*paramVal
);
1216 (void) memset(*paramVal
, 0, strlen((char *)*paramVal
));
1217 (void) __ns_ldap_freeParam(¶mVal
);
1218 if (modparamVal
== NULL
|| *((char *)modparamVal
) == '\0') {
1220 rc
= NS_LDAP_CONFIG
;
1221 *errorp
= __s_api_make_error(NS_CONFIG_SYNTAX
,
1222 gettext("bind password not valid"));
1223 if (*errorp
== NULL
)
1224 rc
= NS_LDAP_MEMORY
;
1228 cred
->cred
.unix_cred
.passwd
= modparamVal
;
1229 return (NS_LDAP_SUCCESS
);
1233 __ns_ldap_is_shadow_update_enabled(void)
1235 int **enable_shadow
= NULL
;
1236 ns_ldap_error_t
*errorp
= NULL
;
1238 if (__ns_ldap_getParam(NS_LDAP_ENABLE_SHADOW_UPDATE_P
,
1239 (void ***)&enable_shadow
, &errorp
) != NS_LDAP_SUCCESS
) {
1241 (void) __ns_ldap_freeError(&errorp
);
1244 if ((enable_shadow
!= NULL
&& *enable_shadow
!= NULL
) &&
1245 (*enable_shadow
[0] == NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE
)) {
1246 (void) __ns_ldap_freeParam((void ***)&enable_shadow
);
1249 if (enable_shadow
!= NULL
)
1250 (void) __ns_ldap_freeParam((void ***)&enable_shadow
);
1255 * __ns_ldap_repAttr modifies ldap attributes of the 'dn' entry stored
1256 * on the LDAP server. 'service' indicates the type of database entries
1257 * to modify. When the Native LDAP client is configured with 'shadow update
1258 * enabled', Shadowshadow(4) entries can only be modified by privileged users.
1259 * Such users use the NS_LDAP_UPDATE_SHADOW flag to indicate the call is
1260 * for such a shadow(4) update, which would be forwarded to ldap_cachemgr
1261 * for performing the LDAP modify operation. ldap_cachemgr would call
1262 * this function again and use the special service NS_ADMIN_SHADOW_UPDATE
1263 * to identify itself, so that admin credential would be obtained and
1264 * the actual LDAP modify operation be done.
1269 const char *service
,
1271 const ns_ldap_attr_t
* const *attr
,
1272 const ns_cred_t
*cred
,
1274 ns_ldap_error_t
** errorp
)
1279 boolean_t shadow_update_enabled
= B_FALSE
;
1282 (void) fprintf(stderr
, "__ns_ldap_repAttr START\n");
1287 if (attr
== NULL
|| *attr
== NULL
|| dn
== NULL
)
1288 return (NS_LDAP_INVALID_PARAM
);
1290 /* Privileged shadow modify? */
1291 if ((flags
& NS_LDAP_UPDATE_SHADOW
) != 0 &&
1292 strcmp(service
, "shadow") == 0) {
1294 /* Shadow update enabled ? If not, error out */
1295 shadow_update_enabled
= __ns_ldap_is_shadow_update_enabled();
1296 if (!shadow_update_enabled
) {
1297 *errorp
= __s_api_make_error(NS_CONFIG_NOTALLOW
,
1298 gettext("Shadow Update is not enabled"));
1299 return (NS_LDAP_CONFIG
);
1302 /* privileged shadow modify requires euid 0 or all zone privs */
1303 priv
= (geteuid() == 0);
1305 priv_set_t
*ps
= priv_allocset(); /* caller */
1306 priv_set_t
*zs
; /* zone */
1308 (void) getppriv(PRIV_EFFECTIVE
, ps
);
1309 zs
= priv_str_to_set("zone", ",", NULL
);
1310 priv
= priv_isequalset(ps
, zs
);
1315 return (NS_LDAP_OP_FAILED
);
1317 rc
= send_to_cachemgr(dn
, (ns_ldap_attr_t
**)attr
, errorp
);
1322 return (NS_LDAP_INVALID_PARAM
);
1325 * If service is NS_ADMIN_SHADOW_UPDATE, the caller should be
1326 * ldap_cachemgr. We need to get the admin cred to do work.
1327 * If the caller is not ldap_cachemgr, but use the service
1328 * NS_ADMIN_SHADOW_UPDATE, get_admin_passwd() will fail,
1329 * as the admin cred is not available to the caller.
1331 if (strcmp(service
, NS_ADMIN_SHADOW_UPDATE
) == 0) {
1332 if ((rc
= get_admin_passwd((ns_cred_t
*)cred
, errorp
)) !=
1337 mods
= __s_api_makeModList(service
, attr
, LDAP_MOD_REPLACE
, flags
);
1339 return (NS_LDAP_MEMORY
);
1341 rc
= write_state_machine(LDAP_REQ_MODIFY
,
1342 (char *)dn
, mods
, cred
, flags
, errorp
);
1351 const char *service
,
1353 const ns_ldap_entry_t
*entry
,
1354 const ns_cred_t
*cred
,
1356 ns_ldap_error_t
** errorp
)
1358 char *new_dn
= NULL
;
1359 LDAPMod
**mods
= NULL
;
1360 const ns_ldap_attr_t
* const *attr
;
1365 (void) fprintf(stderr
, "__ns_ldap_addEntry START\n");
1368 if ((entry
== NULL
) || (dn
== NULL
) || (cred
== NULL
))
1369 return (NS_LDAP_INVALID_PARAM
);
1372 /* Construct array of LDAPMod representing attributes of new entry. */
1374 nAttr
= entry
->attr_count
;
1375 attr
= (const ns_ldap_attr_t
* const *)(entry
->attr_pair
);
1376 mods
= __s_api_makeModListCount(service
, attr
, LDAP_MOD_ADD
,
1379 return (NS_LDAP_MEMORY
);
1382 rc
= replace_mapped_attr_in_dn(service
, dn
, &new_dn
);
1383 if (rc
!= NS_LDAP_SUCCESS
) {
1388 rc
= write_state_machine(LDAP_REQ_ADD
,
1389 new_dn
? new_dn
: (char *)dn
, mods
, cred
, flags
, errorp
);
1400 const char *service
,
1402 const ns_cred_t
*cred
,
1404 ns_ldap_error_t
** errorp
)
1409 (void) fprintf(stderr
, "__ns_ldap_delEntry START\n");
1411 if ((dn
== NULL
) || (cred
== NULL
))
1412 return (NS_LDAP_INVALID_PARAM
);
1416 rc
= write_state_machine(LDAP_REQ_DELETE
,
1417 (char *)dn
, NULL
, cred
, flags
, errorp
);
1423 * Add Typed Entry Helper routines
1427 * Add Typed Entry Conversion routines
1431 __s_add_attr(ns_ldap_entry_t
*e
, char *attrname
, char *value
)
1436 a
= (ns_ldap_attr_t
*)calloc(1, sizeof (ns_ldap_attr_t
));
1438 return (NS_LDAP_MEMORY
);
1439 a
->attrname
= strdup(attrname
);
1440 if (a
->attrname
== NULL
)
1441 return (NS_LDAP_MEMORY
);
1442 a
->attrvalue
= (char **)calloc(1, sizeof (char **));
1443 if (a
->attrvalue
== NULL
)
1444 return (NS_LDAP_MEMORY
);
1446 a
->attrvalue
[0] = NULL
;
1449 return (NS_LDAP_MEMORY
);
1450 a
->attrvalue
[0] = v
;
1451 e
->attr_pair
[e
->attr_count
] = a
;
1453 return (NS_LDAP_SUCCESS
);
1457 __s_add_attrlist(ns_ldap_entry_t
*e
, char *attrname
, char **argv
)
1464 a
= (ns_ldap_attr_t
*)calloc(1, sizeof (ns_ldap_attr_t
));
1466 return (NS_LDAP_MEMORY
);
1467 a
->attrname
= strdup(attrname
);
1468 if (a
->attrname
== NULL
)
1469 return (NS_LDAP_MEMORY
);
1471 for (i
= 0, av
= argv
; *av
!= NULL
; av
++, i
++)
1474 a
->attrvalue
= (char **)calloc(i
, sizeof (char *));
1476 if (a
->attrvalue
== NULL
)
1477 return (NS_LDAP_MEMORY
);
1480 for (j
= 0; j
< i
; j
++) {
1481 v
= strdup(argv
[j
]);
1483 return (NS_LDAP_MEMORY
);
1484 a
->attrvalue
[j
] = v
;
1486 e
->attr_pair
[e
->attr_count
] = a
;
1488 return (NS_LDAP_SUCCESS
);
1491 static ns_ldap_entry_t
*
1492 __s_mk_entry(char **objclass
, int max_attr
)
1495 e
= (ns_ldap_entry_t
*)calloc(1, sizeof (ns_ldap_entry_t
));
1498 /* allocate attributes, +1 for objectclass, +1 for NULL terminator */
1499 e
->attr_pair
= (ns_ldap_attr_t
**)
1500 calloc(max_attr
+ 2, sizeof (ns_ldap_attr_t
*));
1501 if (e
->attr_pair
== NULL
) {
1506 if (__s_add_attrlist(e
, "objectClass", objclass
) != NS_LDAP_SUCCESS
) {
1516 * Conversion: passwd
1517 * Input format: struct passwd
1518 * Exported objectclass: posixAccount
1521 __s_cvt_passwd(const void *data
, char **rdn
,
1522 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1527 /* routine specific */
1531 static char *oclist
[] = {
1539 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1540 return (NS_LDAP_OP_FAILED
);
1541 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1543 return (NS_LDAP_MEMORY
);
1545 /* Convert the structure */
1546 ptr
= (struct passwd
*)data
;
1548 if (ptr
->pw_name
== NULL
|| ptr
->pw_uid
> MAXUID
||
1549 ptr
->pw_gid
> MAXUID
|| ptr
->pw_dir
== NULL
) {
1550 __ns_ldap_freeEntry(e
);
1552 return (NS_LDAP_INVALID_PARAM
);
1555 /* Create an appropriate rdn */
1556 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->pw_name
);
1557 *rdn
= strdup(trdn
);
1559 __ns_ldap_freeEntry(e
);
1561 return (NS_LDAP_MEMORY
);
1564 /* Error check the data and add the attributes */
1565 rc
= __s_add_attr(e
, "uid", ptr
->pw_name
);
1566 if (rc
!= NS_LDAP_SUCCESS
) {
1567 __s_cvt_freeEntryRdn(entry
, rdn
);
1570 rc
= __s_add_attr(e
, "cn", ptr
->pw_name
);
1571 if (rc
!= NS_LDAP_SUCCESS
) {
1572 __s_cvt_freeEntryRdn(entry
, rdn
);
1576 if (ptr
->pw_passwd
!= NULL
&&
1577 ptr
->pw_passwd
[0] != '\0') {
1578 rc
= __s_add_attr(e
, "userPassword", ptr
->pw_passwd
);
1579 if (rc
!= NS_LDAP_SUCCESS
) {
1580 __s_cvt_freeEntryRdn(entry
, rdn
);
1585 (void) sprintf(ibuf
, "%u", ptr
->pw_uid
);
1586 rc
= __s_add_attr(e
, "uidNumber", ibuf
);
1587 if (rc
!= NS_LDAP_SUCCESS
) {
1588 __s_cvt_freeEntryRdn(entry
, rdn
);
1592 (void) sprintf(ibuf
, "%u", ptr
->pw_gid
);
1593 rc
= __s_add_attr(e
, "gidNumber", ibuf
);
1594 if (rc
!= NS_LDAP_SUCCESS
) {
1595 __s_cvt_freeEntryRdn(entry
, rdn
);
1598 if (ptr
->pw_gecos
!= NULL
&&
1599 ptr
->pw_gecos
[0] != '\0') {
1600 rc
= __s_add_attr(e
, "gecos", ptr
->pw_gecos
);
1601 if (rc
!= NS_LDAP_SUCCESS
) {
1602 __s_cvt_freeEntryRdn(entry
, rdn
);
1607 rc
= __s_add_attr(e
, "homeDirectory", ptr
->pw_dir
);
1608 if (rc
!= NS_LDAP_SUCCESS
) {
1609 __s_cvt_freeEntryRdn(entry
, rdn
);
1612 if (ptr
->pw_shell
!= NULL
&&
1613 ptr
->pw_shell
[0] != '\0') {
1614 rc
= __s_add_attr(e
, "loginShell", ptr
->pw_shell
);
1615 if (rc
!= NS_LDAP_SUCCESS
) {
1616 __s_cvt_freeEntryRdn(entry
, rdn
);
1621 return (NS_LDAP_SUCCESS
);
1625 * escape_str function escapes special characters in str and
1626 * copies to escstr string.
1628 * return 0 for successful
1631 static int escape_str(char *escstr
, char *str
)
1635 while ((*str
!= '\0') && (index
< (RDNSIZE
- 1))) {
1636 if (*str
== '+' || *str
== ';' || *str
== '>' ||
1637 *str
== '<' || *str
== ',' || *str
== '"' ||
1638 *str
== '\\' || *str
== '=' ||
1639 (*str
== '#' && index
== 0)) {
1658 * Conversion: project
1659 * Input format: struct project
1660 * Exported objectclass: SolarisProject
1663 __s_cvt_project(const void *data
, char **rdn
,
1664 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1670 /* routine specific */
1671 struct project
*ptr
;
1674 static char *oclist
[] = {
1680 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1681 return (NS_LDAP_OP_FAILED
);
1683 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1685 return (NS_LDAP_MEMORY
);
1687 /* Convert the structure */
1688 ptr
= (struct project
*)data
;
1690 if (ptr
->pj_name
== NULL
|| ptr
->pj_projid
> MAXUID
) {
1691 __ns_ldap_freeEntry(e
);
1693 return (NS_LDAP_INVALID_PARAM
);
1696 /* Create an appropriate rdn */
1697 (void) snprintf(trdn
, RDNSIZE
, "SolarisProjectName=%s", ptr
->pj_name
);
1698 *rdn
= strdup(trdn
);
1700 __ns_ldap_freeEntry(e
);
1702 return (NS_LDAP_MEMORY
);
1705 /* Error check the data and add the attributes */
1708 rc
= __s_add_attr(e
, "SolarisProjectName", ptr
->pj_name
);
1709 if (rc
!= NS_LDAP_SUCCESS
) {
1710 __s_cvt_freeEntryRdn(entry
, rdn
);
1716 * ibuf is 11 chars big, which should be enough for string
1717 * representation of 32bit number + nul-car
1719 if (snprintf(ibuf
, sizeof (ibuf
), "%u", ptr
->pj_projid
) < 0) {
1720 __s_cvt_freeEntryRdn(entry
, rdn
);
1721 return (NS_LDAP_INVALID_PARAM
);
1723 rc
= __s_add_attr(e
, "SolarisProjectID", ibuf
);
1724 if (rc
!= NS_LDAP_SUCCESS
) {
1725 __s_cvt_freeEntryRdn(entry
, rdn
);
1729 /* Comment/Description */
1730 if (ptr
->pj_comment
!= NULL
&& ptr
->pj_comment
[0] != '\0') {
1731 rc
= __s_add_attr(e
, "description", ptr
->pj_comment
);
1732 if (rc
!= NS_LDAP_SUCCESS
) {
1733 __s_cvt_freeEntryRdn(entry
, rdn
);
1739 if (ptr
->pj_attr
!= NULL
&& ptr
->pj_attr
[0] != '\0') {
1740 rc
= __s_add_attr(e
, "SolarisProjectAttr", ptr
->pj_attr
);
1741 if (rc
!= NS_LDAP_SUCCESS
) {
1742 __s_cvt_freeEntryRdn(entry
, rdn
);
1748 if (ptr
->pj_users
!= NULL
) {
1749 rc
= __s_add_attrlist(e
, "memberUid", ptr
->pj_users
);
1750 if (rc
!= NS_LDAP_SUCCESS
) {
1751 __s_cvt_freeEntryRdn(entry
, rdn
);
1757 if (ptr
->pj_groups
!= NULL
) {
1758 rc
= __s_add_attrlist(e
, "memberGid", ptr
->pj_groups
);
1759 if (rc
!= NS_LDAP_SUCCESS
) {
1760 __s_cvt_freeEntryRdn(entry
, rdn
);
1767 return (NS_LDAP_SUCCESS
);
1770 * Conversion: shadow
1771 * Input format: struct shadow
1772 * Exported objectclass: shadowAccount
1775 __s_cvt_shadow(const void *data
, char **rdn
,
1776 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1781 /* routine specific */
1785 static char *oclist
[] = {
1793 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1794 return (NS_LDAP_OP_FAILED
);
1795 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1797 return (NS_LDAP_MEMORY
);
1799 /* Convert the structure */
1800 ptr
= (struct spwd
*)data
;
1802 if (ptr
->sp_namp
== NULL
) {
1803 __ns_ldap_freeEntry(e
);
1805 return (NS_LDAP_INVALID_PARAM
);
1808 /* Create an appropriate rdn */
1809 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->sp_namp
);
1810 *rdn
= strdup(trdn
);
1812 __ns_ldap_freeEntry(e
);
1814 return (NS_LDAP_MEMORY
);
1817 /* Error check the data and add the attributes */
1818 rc
= __s_add_attr(e
, "uid", ptr
->sp_namp
);
1819 if (rc
!= NS_LDAP_SUCCESS
) {
1820 __s_cvt_freeEntryRdn(entry
, rdn
);
1824 if (ptr
->sp_pwdp
== NULL
) {
1825 __s_cvt_freeEntryRdn(entry
, rdn
);
1826 return (NS_LDAP_INVALID_PARAM
);
1828 rc
= __s_add_attr(e
, "userPassword", ptr
->sp_pwdp
);
1829 if (rc
!= NS_LDAP_SUCCESS
) {
1830 __s_cvt_freeEntryRdn(entry
, rdn
);
1834 if (ptr
->sp_lstchg
>= 0) {
1835 (void) sprintf(ibuf
, "%d", ptr
->sp_lstchg
);
1836 rc
= __s_add_attr(e
, "shadowLastChange", ibuf
);
1837 if (rc
!= NS_LDAP_SUCCESS
) {
1838 __s_cvt_freeEntryRdn(entry
, rdn
);
1842 if (ptr
->sp_min
>= 0) {
1843 (void) sprintf(ibuf
, "%d", ptr
->sp_min
);
1844 rc
= __s_add_attr(e
, "shadowMin", ibuf
);
1845 if (rc
!= NS_LDAP_SUCCESS
) {
1846 __s_cvt_freeEntryRdn(entry
, rdn
);
1850 if (ptr
->sp_max
>= 0) {
1851 (void) sprintf(ibuf
, "%d", ptr
->sp_max
);
1852 rc
= __s_add_attr(e
, "shadowMax", ibuf
);
1853 if (rc
!= NS_LDAP_SUCCESS
) {
1854 __s_cvt_freeEntryRdn(entry
, rdn
);
1858 if (ptr
->sp_warn
>= 0) {
1859 (void) sprintf(ibuf
, "%d", ptr
->sp_warn
);
1860 rc
= __s_add_attr(e
, "shadowWarning", ibuf
);
1861 if (rc
!= NS_LDAP_SUCCESS
) {
1862 __s_cvt_freeEntryRdn(entry
, rdn
);
1866 if (ptr
->sp_inact
>= 0) {
1867 (void) sprintf(ibuf
, "%d", ptr
->sp_inact
);
1868 rc
= __s_add_attr(e
, "shadowInactive", ibuf
);
1869 if (rc
!= NS_LDAP_SUCCESS
) {
1870 __s_cvt_freeEntryRdn(entry
, rdn
);
1874 if (ptr
->sp_expire
>= 0) {
1875 (void) sprintf(ibuf
, "%d", ptr
->sp_expire
);
1876 rc
= __s_add_attr(e
, "shadowExpire", ibuf
);
1877 if (rc
!= NS_LDAP_SUCCESS
) {
1878 __s_cvt_freeEntryRdn(entry
, rdn
);
1882 (void) sprintf(ibuf
, "%d", ptr
->sp_flag
);
1883 rc
= __s_add_attr(e
, "shadowFlag", ibuf
);
1884 if (rc
!= NS_LDAP_SUCCESS
) {
1885 __s_cvt_freeEntryRdn(entry
, rdn
);
1889 return (NS_LDAP_SUCCESS
);
1895 * Input format: struct group
1896 * Exported objectclass: posixGroup
1899 __s_cvt_group(const void *data
, char **rdn
,
1900 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
1905 /* routine specific */
1911 static char *oclist
[] = {
1917 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
1918 return (NS_LDAP_OP_FAILED
);
1919 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
1921 return (NS_LDAP_MEMORY
);
1923 /* Convert the structure */
1924 ptr
= (struct group
*)data
;
1926 if (ptr
->gr_name
== NULL
|| ptr
->gr_gid
> MAXUID
) {
1927 __ns_ldap_freeEntry(e
);
1929 return (NS_LDAP_INVALID_PARAM
);
1932 /* Create an appropriate rdn */
1933 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->gr_name
);
1934 *rdn
= strdup(trdn
);
1936 __ns_ldap_freeEntry(e
);
1938 return (NS_LDAP_MEMORY
);
1941 /* Error check the data and add the attributes */
1942 rc
= __s_add_attr(e
, "cn", ptr
->gr_name
);
1943 if (rc
!= NS_LDAP_SUCCESS
) {
1944 __s_cvt_freeEntryRdn(entry
, rdn
);
1948 (void) sprintf(ibuf
, "%u", ptr
->gr_gid
);
1949 rc
= __s_add_attr(e
, "gidNumber", ibuf
);
1950 if (rc
!= NS_LDAP_SUCCESS
) {
1951 __s_cvt_freeEntryRdn(entry
, rdn
);
1954 if (ptr
->gr_passwd
&& ptr
->gr_passwd
[0] != '\0') {
1955 rc
= __s_add_attr(e
, "userPassword", ptr
->gr_passwd
);
1956 if (rc
!= NS_LDAP_SUCCESS
) {
1957 __s_cvt_freeEntryRdn(entry
, rdn
);
1962 if (ptr
->gr_mem
&& ptr
->gr_mem
[0]) {
1964 for (i
= 0; *lm
; i
++, lm
++)
1967 nm
= (char **)calloc(i
+2, sizeof (char *));
1969 __s_cvt_freeEntryRdn(entry
, rdn
);
1970 return (NS_LDAP_MEMORY
);
1972 for (j
= 0; j
< i
; j
++) {
1973 nm
[j
] = strdup(lm
[j
]);
1974 if (nm
[j
] == NULL
) {
1975 for (k
= 0; k
< j
; k
++)
1978 __s_cvt_freeEntryRdn(entry
, rdn
);
1979 return (NS_LDAP_MEMORY
);
1982 rc
= __s_add_attrlist(e
, "memberUid", nm
);
1983 for (j
= 0; j
< i
; j
++) {
1988 if (rc
!= NS_LDAP_SUCCESS
) {
1989 __s_cvt_freeEntryRdn(entry
, rdn
);
1994 return (NS_LDAP_SUCCESS
);
1999 * Input format: struct hostent
2000 * Exported objectclass: ipHost
2003 __s_cvt_hosts(const void *data
, char **rdn
,
2004 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2009 /* routine specific */
2010 struct hostent
*ptr
;
2014 static char *oclist
[] = {
2021 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2022 return (NS_LDAP_OP_FAILED
);
2023 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2025 return (NS_LDAP_MEMORY
);
2027 /* Convert the structure */
2028 ptr
= (struct hostent
*)data
;
2030 if (ptr
->h_name
== NULL
||
2031 ptr
->h_addr_list
== NULL
|| ptr
->h_addr_list
[0] == NULL
) {
2032 __ns_ldap_freeEntry(e
);
2034 return (NS_LDAP_INVALID_PARAM
);
2037 /* Create an appropriate rdn */
2038 (void) snprintf(trdn
, RDNSIZE
, "cn=%s+ipHostNumber=%s",
2039 ptr
->h_name
, ptr
->h_addr_list
[0]);
2040 *rdn
= strdup(trdn
);
2042 __ns_ldap_freeEntry(e
);
2044 return (NS_LDAP_MEMORY
);
2047 /* Error check the data and add the attributes */
2048 if (ptr
->h_aliases
&& ptr
->h_aliases
[0]) {
2049 lm
= ptr
->h_aliases
;
2051 * If there is a description, 'i' will contain
2052 * the index of the description in the aliases list
2054 for (i
= 0; *lm
&& (*lm
)[0] != '#'; i
++, lm
++)
2056 lm
= ptr
->h_aliases
;
2057 nm
= (char **)calloc(i
+2, sizeof (char *));
2059 __s_cvt_freeEntryRdn(entry
, rdn
);
2060 return (NS_LDAP_MEMORY
);
2062 nm
[0] = ptr
->h_name
;
2063 for (j
= 0; j
< i
; j
++)
2064 nm
[j
+1] = ptr
->h_aliases
[j
];
2066 rc
= __s_add_attrlist(e
, "cn", nm
);
2068 if (rc
!= NS_LDAP_SUCCESS
) {
2069 __s_cvt_freeEntryRdn(entry
, rdn
);
2074 if (lm
[i
] && lm
[i
][0] == '#') {
2075 nm
[0] = &(lm
[i
][1]);
2077 rc
= __s_add_attrlist(e
, "description", nm
);
2081 if (rc
!= NS_LDAP_SUCCESS
) {
2082 __s_cvt_freeEntryRdn(entry
, rdn
);
2086 rc
= __s_add_attr(e
, "cn", ptr
->h_name
);
2087 if (rc
!= NS_LDAP_SUCCESS
) {
2088 __s_cvt_freeEntryRdn(entry
, rdn
);
2093 if (ptr
->h_addr_list
&& ptr
->h_addr_list
[0]) {
2094 lm
= ptr
->h_addr_list
;
2095 for (i
= 0; *lm
; i
++, lm
++)
2097 lm
= ptr
->h_addr_list
;
2098 nm
= (char **)calloc(i
+2, sizeof (char *));
2100 __s_cvt_freeEntryRdn(entry
, rdn
);
2101 return (NS_LDAP_MEMORY
);
2103 for (j
= 0; j
< i
; j
++) {
2104 nm
[j
] = strdup(lm
[j
]);
2105 if (nm
[j
] == NULL
) {
2106 for (k
= 0; k
< j
; k
++)
2109 __s_cvt_freeEntryRdn(entry
, rdn
);
2110 return (NS_LDAP_MEMORY
);
2113 rc
= __s_add_attrlist(e
, "ipHostNumber", nm
);
2114 for (j
= 0; j
< i
; j
++) {
2119 if (rc
!= NS_LDAP_SUCCESS
) {
2120 __s_cvt_freeEntryRdn(entry
, rdn
);
2124 __s_cvt_freeEntryRdn(entry
, rdn
);
2125 return (NS_LDAP_INVALID_PARAM
);
2128 return (NS_LDAP_SUCCESS
);
2133 * Input format: struct rpcent
2134 * Exported objectclass: oncRpc
2137 __s_cvt_rpc(const void *data
, char **rdn
,
2138 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2143 /* routine specific */
2149 static char *oclist
[] = {
2155 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2156 return (NS_LDAP_OP_FAILED
);
2157 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2159 return (NS_LDAP_MEMORY
);
2161 /* Convert the structure */
2162 ptr
= (struct rpcent
*)data
;
2164 if (ptr
->r_name
== NULL
|| ptr
->r_number
< 0) {
2165 __ns_ldap_freeEntry(e
);
2167 return (NS_LDAP_INVALID_PARAM
);
2170 /* Create an appropriate rdn */
2171 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->r_name
);
2172 *rdn
= strdup(trdn
);
2174 __ns_ldap_freeEntry(e
);
2176 return (NS_LDAP_MEMORY
);
2179 /* Error check the data and add the attributes */
2180 if (ptr
->r_aliases
&& ptr
->r_aliases
[0]) {
2181 nm
= ptr
->r_aliases
;
2182 for (i
= 0; *nm
; i
++, nm
++)
2184 nm
= (char **)calloc(i
+2, sizeof (char *));
2186 __s_cvt_freeEntryRdn(entry
, rdn
);
2187 return (NS_LDAP_MEMORY
);
2189 nm
[0] = ptr
->r_name
;
2190 for (j
= 0; j
< i
; j
++)
2191 nm
[j
+1] = ptr
->r_aliases
[j
];
2193 rc
= __s_add_attrlist(e
, "cn", nm
);
2196 if (rc
!= NS_LDAP_SUCCESS
) {
2197 __s_cvt_freeEntryRdn(entry
, rdn
);
2201 rc
= __s_add_attr(e
, "cn", ptr
->r_name
);
2202 if (rc
!= NS_LDAP_SUCCESS
) {
2203 __s_cvt_freeEntryRdn(entry
, rdn
);
2208 if (ptr
->r_number
>= 0) {
2209 (void) sprintf(ibuf
, "%d", ptr
->r_number
);
2210 rc
= __s_add_attr(e
, "oncRpcNumber", ibuf
);
2211 if (rc
!= NS_LDAP_SUCCESS
) {
2212 __s_cvt_freeEntryRdn(entry
, rdn
);
2217 return (NS_LDAP_SUCCESS
);
2222 * Conversion: protocols
2223 * Input format: struct protoent
2224 * Exported objectclass: ipProtocol
2227 __s_cvt_protocols(const void *data
, char **rdn
,
2228 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2233 /* routine specific */
2234 struct protoent
*ptr
;
2239 static char *oclist
[] = {
2245 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2246 return (NS_LDAP_OP_FAILED
);
2247 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2249 return (NS_LDAP_MEMORY
);
2251 /* Convert the structure */
2252 ptr
= (struct protoent
*)data
;
2254 if (ptr
->p_name
== NULL
|| ptr
->p_proto
< 0) {
2255 __ns_ldap_freeEntry(e
);
2257 return (NS_LDAP_INVALID_PARAM
);
2260 /* Create an appropriate rdn */
2261 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->p_name
);
2262 *rdn
= strdup(trdn
);
2264 __ns_ldap_freeEntry(e
);
2266 return (NS_LDAP_MEMORY
);
2269 /* Error check the data and add the attributes */
2270 if (ptr
->p_aliases
&& ptr
->p_aliases
[0]) {
2271 nm
= ptr
->p_aliases
;
2272 for (i
= 0; *nm
; i
++, nm
++)
2274 nm
= (char **)calloc(i
+2, sizeof (char *));
2276 __s_cvt_freeEntryRdn(entry
, rdn
);
2277 return (NS_LDAP_MEMORY
);
2279 nm
[0] = ptr
->p_name
;
2280 for (j
= 0; j
< i
; j
++)
2281 nm
[j
+1] = ptr
->p_aliases
[j
];
2283 rc
= __s_add_attrlist(e
, "cn", nm
);
2286 if (rc
!= NS_LDAP_SUCCESS
) {
2287 __s_cvt_freeEntryRdn(entry
, rdn
);
2291 rc
= __s_add_attr(e
, "cn", ptr
->p_name
);
2292 if (rc
!= NS_LDAP_SUCCESS
) {
2293 __s_cvt_freeEntryRdn(entry
, rdn
);
2298 (void) sprintf(ibuf
, "%d", ptr
->p_proto
);
2299 rc
= __s_add_attr(e
, "ipProtocolNumber", ibuf
);
2300 if (rc
!= NS_LDAP_SUCCESS
) {
2301 __s_cvt_freeEntryRdn(entry
, rdn
);
2305 return (NS_LDAP_SUCCESS
);
2310 * Conversion: services
2311 * Input format: struct servent
2312 * Exported objectclass: ipService
2315 __s_cvt_services(const void *data
, char **rdn
,
2316 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2321 char esc_str
[RDNSIZE
];
2322 /* routine specific */
2323 struct servent
*ptr
;
2328 static char *oclist
[] = {
2334 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2335 return (NS_LDAP_OP_FAILED
);
2336 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2338 return (NS_LDAP_MEMORY
);
2340 /* Convert the structure */
2341 ptr
= (struct servent
*)data
;
2343 if (ptr
->s_name
== NULL
|| ptr
->s_port
< 0 || ptr
->s_proto
== NULL
) {
2344 __ns_ldap_freeEntry(e
);
2346 return (NS_LDAP_INVALID_PARAM
);
2350 * Escape special characters in service name.
2352 if (escape_str(esc_str
, ptr
->s_name
) != 0) {
2353 __ns_ldap_freeEntry(e
);
2355 return (NS_LDAP_INVALID_PARAM
);
2358 /* Create an appropriate rdn */
2359 (void) snprintf(trdn
, RDNSIZE
, "cn=%s+ipServiceProtocol=%s",
2360 esc_str
, ptr
->s_proto
);
2362 *rdn
= strdup(trdn
);
2364 __ns_ldap_freeEntry(e
);
2366 return (NS_LDAP_MEMORY
);
2369 /* Error check the data and add the attributes */
2370 if (ptr
->s_aliases
&& ptr
->s_aliases
[0]) {
2371 nm
= ptr
->s_aliases
;
2372 for (i
= 0; *nm
; i
++, nm
++)
2374 nm
= (char **)calloc(i
+2, sizeof (char *));
2376 __s_cvt_freeEntryRdn(entry
, rdn
);
2377 return (NS_LDAP_MEMORY
);
2379 nm
[0] = ptr
->s_name
;
2380 for (j
= 0; j
< i
; j
++)
2381 nm
[j
+1] = ptr
->s_aliases
[j
];
2383 rc
= __s_add_attrlist(e
, "cn", nm
);
2386 if (rc
!= NS_LDAP_SUCCESS
) {
2387 __s_cvt_freeEntryRdn(entry
, rdn
);
2391 rc
= __s_add_attr(e
, "cn", ptr
->s_name
);
2392 if (rc
!= NS_LDAP_SUCCESS
) {
2393 __s_cvt_freeEntryRdn(entry
, rdn
);
2398 (void) sprintf(ibuf
, "%d", ptr
->s_port
);
2399 rc
= __s_add_attr(e
, "ipServicePort", ibuf
);
2400 if (rc
!= NS_LDAP_SUCCESS
) {
2401 __s_cvt_freeEntryRdn(entry
, rdn
);
2404 rc
= __s_add_attr(e
, "ipServiceProtocol", ptr
->s_proto
);
2405 if (rc
!= NS_LDAP_SUCCESS
) {
2406 __s_cvt_freeEntryRdn(entry
, rdn
);
2410 return (NS_LDAP_SUCCESS
);
2414 * Conversion: networks
2415 * Input format: struct netent
2416 * Exported objectclass: ipNetwork
2419 __s_cvt_networks(const void *data
, char **rdn
,
2420 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2425 /* routine specific */
2431 static char *oclist
[] = {
2437 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2438 return (NS_LDAP_OP_FAILED
);
2439 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2441 return (NS_LDAP_MEMORY
);
2443 /* Convert the structure */
2444 ptr
= (struct netent
*)data
;
2446 if (ptr
->n_name
== NULL
|| ptr
->n_net
== 0) {
2447 __ns_ldap_freeEntry(e
);
2449 return (NS_LDAP_INVALID_PARAM
);
2452 (void) snprintf(cp
, sizeof (cp
), "%d.%d.%d.%d",
2453 (ptr
->n_net
& 0xFF000000) >> 24,
2454 (ptr
->n_net
& 0x00FF0000) >> 16,
2455 (ptr
->n_net
& 0x0000FF00) >> 8,
2456 (ptr
->n_net
& 0x000000FF));
2458 /* Create an appropriate rdn */
2459 (void) snprintf(trdn
, RDNSIZE
, "ipNetworkNumber=%s", cp
);
2460 *rdn
= strdup(trdn
);
2462 __ns_ldap_freeEntry(e
);
2464 return (NS_LDAP_MEMORY
);
2467 /* Error check the data and add the attributes */
2468 if (ptr
->n_aliases
&& ptr
->n_aliases
[0]) {
2469 nm
= ptr
->n_aliases
;
2470 for (i
= 0; *nm
; i
++, nm
++)
2472 nm
= (char **)calloc(i
+2, sizeof (char *));
2474 __s_cvt_freeEntryRdn(entry
, rdn
);
2475 return (NS_LDAP_MEMORY
);
2477 nm
[0] = ptr
->n_name
;
2478 for (j
= 0; j
< i
; j
++)
2479 nm
[j
+1] = ptr
->n_aliases
[j
];
2481 rc
= __s_add_attrlist(e
, "cn", nm
);
2484 if (rc
!= NS_LDAP_SUCCESS
) {
2485 __s_cvt_freeEntryRdn(entry
, rdn
);
2489 rc
= __s_add_attr(e
, "cn", ptr
->n_name
);
2490 if (rc
!= NS_LDAP_SUCCESS
) {
2491 __s_cvt_freeEntryRdn(entry
, rdn
);
2496 rc
= __s_add_attr(e
, "ipNetworkNumber", cp
);
2497 if (rc
!= NS_LDAP_SUCCESS
) {
2498 __s_cvt_freeEntryRdn(entry
, rdn
);
2502 return (NS_LDAP_SUCCESS
);
2506 * Conversion: netmasks
2507 * Input format: struct _ns_netmasks
2508 * Exported objectclass: ipNetwork
2511 __s_cvt_netmasks(const void *data
, char **rdn
,
2512 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2517 /* routine specific */
2518 struct _ns_netmasks
*ptr
;
2520 static char *oclist
[] = {
2526 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2527 return (NS_LDAP_OP_FAILED
);
2528 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2530 return (NS_LDAP_MEMORY
);
2532 /* Convert the structure */
2533 ptr
= (struct _ns_netmasks
*)data
;
2535 if (ptr
->netnumber
== NULL
) {
2536 __ns_ldap_freeEntry(e
);
2538 return (NS_LDAP_INVALID_PARAM
);
2541 /* Create an appropriate rdn */
2542 (void) snprintf(trdn
, RDNSIZE
, "ipNetworkNumber=%s", ptr
->netnumber
);
2543 *rdn
= strdup(trdn
);
2545 __ns_ldap_freeEntry(e
);
2547 return (NS_LDAP_MEMORY
);
2550 /* Error check the data and add the attributes */
2551 rc
= __s_add_attr(e
, "ipNetworkNumber", ptr
->netnumber
);
2552 if (rc
!= NS_LDAP_SUCCESS
) {
2553 __s_cvt_freeEntryRdn(entry
, rdn
);
2557 if (ptr
->netmask
!= NULL
) {
2558 rc
= __s_add_attr(e
, "ipNetmaskNumber", ptr
->netmask
);
2559 if (rc
!= NS_LDAP_SUCCESS
) {
2560 __s_cvt_freeEntryRdn(entry
, rdn
);
2565 return (NS_LDAP_SUCCESS
);
2569 * Conversion: netgroups
2570 * Input format: struct _ns_netgroups
2571 * Exported objectclass: nisNetgroup
2574 __s_cvt_netgroups(const void *data
, char **rdn
,
2575 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2580 /* routine specific */
2581 struct _ns_netgroups
*ptr
;
2585 static char *oclist
[] = {
2591 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2592 return (NS_LDAP_OP_FAILED
);
2593 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2595 return (NS_LDAP_MEMORY
);
2597 /* Convert the structure */
2598 ptr
= (struct _ns_netgroups
*)data
;
2600 if (ptr
->name
== NULL
|| *ptr
->name
== '\0') {
2601 __ns_ldap_freeEntry(e
);
2603 return (NS_LDAP_INVALID_PARAM
);
2606 /* Create an appropriate rdn */
2607 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2608 *rdn
= strdup(trdn
);
2610 __ns_ldap_freeEntry(e
);
2612 return (NS_LDAP_MEMORY
);
2615 rc
= __s_add_attr(e
, "cn", ptr
->name
);
2616 if (rc
!= NS_LDAP_SUCCESS
) {
2617 __s_cvt_freeEntryRdn(entry
, rdn
);
2621 /* Error check the data and add the attributes */
2622 if (ptr
->triplet
&& ptr
->triplet
[0]) {
2624 for (i
= 0; *nm
; i
++, nm
++)
2626 nm
= (char **)calloc(i
+2, sizeof (char *));
2628 __s_cvt_freeEntryRdn(entry
, rdn
);
2629 return (NS_LDAP_MEMORY
);
2631 for (j
= 0; j
< i
; j
++)
2632 nm
[j
] = ptr
->triplet
[j
];
2634 rc
= __s_add_attrlist(e
, "nisNetgroupTriple", nm
);
2637 if (rc
!= NS_LDAP_SUCCESS
) {
2638 __s_cvt_freeEntryRdn(entry
, rdn
);
2642 if (ptr
->netgroup
&& ptr
->netgroup
[0]) {
2644 for (i
= 0; *nm
; i
++, nm
++)
2646 nm
= (char **)calloc(i
+2, sizeof (char *));
2648 __s_cvt_freeEntryRdn(entry
, rdn
);
2649 return (NS_LDAP_MEMORY
);
2651 for (j
= 0; j
< i
; j
++)
2652 nm
[j
] = ptr
->netgroup
[j
];
2654 rc
= __s_add_attrlist(e
, "memberNisNetgroup", nm
);
2657 if (rc
!= NS_LDAP_SUCCESS
) {
2658 __s_cvt_freeEntryRdn(entry
, rdn
);
2662 return (NS_LDAP_SUCCESS
);
2665 * Conversion: bootparams
2666 * Input format: struct _ns_bootp
2667 * Exported objectclass: bootableDevice, device
2670 __s_cvt_bootparams(const void *data
, char **rdn
,
2671 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2676 /* routine specific */
2677 struct _ns_bootp
*ptr
;
2681 static char *oclist
[] = {
2688 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2689 return (NS_LDAP_OP_FAILED
);
2690 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2692 return (NS_LDAP_MEMORY
);
2694 /* Convert the structure */
2695 ptr
= (struct _ns_bootp
*)data
;
2697 if (ptr
->name
== NULL
|| *ptr
->name
== '\0') {
2698 __ns_ldap_freeEntry(e
);
2700 return (NS_LDAP_INVALID_PARAM
);
2703 /* Create an appropriate rdn */
2704 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2705 *rdn
= strdup(trdn
);
2707 __ns_ldap_freeEntry(e
);
2709 return (NS_LDAP_MEMORY
);
2712 rc
= __s_add_attr(e
, "cn", ptr
->name
);
2713 if (rc
!= NS_LDAP_SUCCESS
) {
2714 __s_cvt_freeEntryRdn(entry
, rdn
);
2718 /* Error check the data and add the attributes */
2719 if (ptr
->param
&& ptr
->param
[0]) {
2721 for (i
= 0; *nm
; i
++, nm
++)
2723 nm
= (char **)calloc(i
+2, sizeof (char *));
2725 __s_cvt_freeEntryRdn(entry
, rdn
);
2726 return (NS_LDAP_MEMORY
);
2728 for (j
= 0; j
< i
; j
++)
2729 nm
[j
] = ptr
->param
[j
];
2731 rc
= __s_add_attrlist(e
, "bootParameter", nm
);
2734 if (rc
!= NS_LDAP_SUCCESS
) {
2735 __s_cvt_freeEntryRdn(entry
, rdn
);
2740 return (NS_LDAP_SUCCESS
);
2744 * Conversion: ethers
2745 * Input format: struct _ns_ethers
2746 * Exported objectclass: ieee802Device, device
2749 __s_cvt_ethers(const void *data
, char **rdn
,
2750 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2755 /* routine specific */
2756 struct _ns_ethers
*ptr
;
2758 static char *oclist
[] = {
2765 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2766 return (NS_LDAP_OP_FAILED
);
2767 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2769 return (NS_LDAP_MEMORY
);
2771 /* Convert the structure */
2772 ptr
= (struct _ns_ethers
*)data
;
2774 if (ptr
->name
== NULL
|| *ptr
->name
== '\0' || ptr
->ether
== NULL
) {
2775 __ns_ldap_freeEntry(e
);
2777 return (NS_LDAP_INVALID_PARAM
);
2780 /* Create an appropriate rdn */
2781 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2782 *rdn
= strdup(trdn
);
2784 __ns_ldap_freeEntry(e
);
2786 return (NS_LDAP_MEMORY
);
2789 /* Error check the data and add the attributes */
2790 rc
= __s_add_attr(e
, "cn", ptr
->name
);
2791 if (rc
!= NS_LDAP_SUCCESS
) {
2792 __s_cvt_freeEntryRdn(entry
, rdn
);
2796 rc
= __s_add_attr(e
, "macAddress", ptr
->ether
);
2797 if (rc
!= NS_LDAP_SUCCESS
) {
2798 __s_cvt_freeEntryRdn(entry
, rdn
);
2802 return (NS_LDAP_SUCCESS
);
2805 * This function is used when processing an ethers (objectclass: ieee802Device)
2806 * or a bootparams (objectclass: bootableDevice) entry, and the entry is
2807 * already found in LDAP. Since both ethers and bootparams share the same
2808 * LDAP container, we want to check that the entry found in LDAP is:
2809 * - either the same entry (same cn, same objectclass): we don't do anything
2811 * - or an entry which does not have the objectclass we are interesting in:
2812 * in this case, we modify the existing entry by adding the relevant
2813 * objectclass (ieee802Device or bootableDevice) and the relevant attribute(s)
2814 * from the attribute list previously computing by the relevant conversion
2816 * Note: from conversion functions __s_cvt_ethers() and __s_cvt_bootparams()
2817 * we know that there is only 1 more attribute today to add (macAddress
2820 #define _MAX_ATTR_ETHBOOTP 2
2822 modify_ethers_bootp(
2823 const char *service
,
2826 const ns_ldap_attr_t
* const *attrlist
,
2827 const ns_cred_t
*cred
,
2829 ns_ldap_error_t
**errorp
)
2831 char filter
[BUFSIZ
];
2832 ns_ldap_result_t
*resultp
;
2835 ns_ldap_attr_t
*new_attrlist
[_MAX_ATTR_ETHBOOTP
+1];
2836 ns_ldap_attr_t new_attrlist0
;
2837 char *new_attrvalue0
[1];
2838 const ns_ldap_attr_t
* const *aptr
= attrlist
;
2839 ns_ldap_attr_t
*aptr2
;
2840 ns_ldap_error_t
*new_errorp
= NULL
;
2842 if (rdn
== NULL
|| fulldn
== NULL
|| attrlist
== NULL
||
2843 errorp
== NULL
|| service
== NULL
)
2844 return (NS_LDAP_OP_FAILED
);
2846 bzero(&new_attrlist
, sizeof (new_attrlist
));
2847 bzero(&new_attrlist0
, sizeof (new_attrlist0
));
2848 new_attrlist
[0] = &new_attrlist0
;
2849 new_attrlist
[0]->attrvalue
= new_attrvalue0
;
2851 new_attrlist
[0]->attrname
= "objectclass";
2852 new_attrlist
[0]->value_count
= 1;
2853 if (strcasecmp(service
, "ethers") == 0) {
2854 (void) snprintf(&filter
[0], sizeof (filter
),
2855 "(&(objectClass=ieee802Device)(%s))", rdn
);
2856 new_attrlist
[0]->attrvalue
[0] = "ieee802Device";
2858 (void) snprintf(&filter
[0], sizeof (filter
),
2859 "(&(objectClass=bootableDevice)(%s))", rdn
);
2860 new_attrlist
[0]->attrvalue
[0] = "bootableDevice";
2863 rc
= __ns_ldap_list(service
, filter
, NULL
, (const char **)NULL
,
2864 NULL
, NS_LDAP_SCOPE_SUBTREE
, &resultp
, &new_errorp
,
2868 case NS_LDAP_SUCCESS
:
2870 * entry already exists for this service
2871 * return NS_LDAP_INTERNAL and do not modify the incoming errorp
2873 rc
= NS_LDAP_INTERNAL
;
2875 case NS_LDAP_NOTFOUND
:
2877 * entry not found with the given objectclasss but entry exists
2878 * hence add the relevant attribute (macAddress or bootparams).
2881 while (*aptr
&& (i
< _MAX_ATTR_ETHBOOTP
)) {
2882 /* aptr2 needed here to avoid lint warning */
2883 aptr2
= (ns_ldap_attr_t
*)*aptr
++;
2884 if ((strcasecmp(aptr2
->attrname
, "cn") != 0) &&
2885 (strcasecmp(aptr2
->attrname
,
2886 "objectclass") != 0)) {
2887 new_attrlist
[i
++] = (ns_ldap_attr_t
*)aptr2
;
2891 if (i
!= _MAX_ATTR_ETHBOOTP
) {
2892 /* we haven't found all expected attributes */
2893 rc
= NS_LDAP_OP_FAILED
;
2897 aptr
= (const ns_ldap_attr_t
* const *) new_attrlist
;
2898 /* clean errorp first */
2899 (void) __ns_ldap_freeError(errorp
);
2900 rc
= __ns_ldap_addAttr(service
, fulldn
, aptr
, cred
, flags
,
2905 * unexpected error happenned
2906 * returning relevant error
2908 (void) __ns_ldap_freeError(errorp
);
2909 *errorp
= new_errorp
;
2917 * Conversion: publickey
2918 * Input format: struct _ns_pubkey
2919 * Exported objectclass: NisKeyObject
2922 __s_cvt_publickey(const void *data
, char **rdn
,
2923 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2928 /* routine specific */
2929 struct _ns_pubkey
*ptr
;
2931 static char *oclist
[] = {
2936 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
2937 return (NS_LDAP_OP_FAILED
);
2938 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
2940 return (NS_LDAP_MEMORY
);
2942 /* Convert the structure */
2943 ptr
= (struct _ns_pubkey
*)data
;
2945 if (ptr
->name
== NULL
|| *ptr
->name
== '\0' || ptr
->pubkey
== NULL
||
2946 ptr
->privkey
== NULL
) {
2947 __ns_ldap_freeEntry(e
);
2949 return (NS_LDAP_INVALID_PARAM
);
2952 /* Create an appropriate rdn */
2953 if (ptr
->hostcred
== NS_HOSTCRED_FALSE
)
2954 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->name
);
2956 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
2957 *rdn
= strdup(trdn
);
2959 __ns_ldap_freeEntry(e
);
2961 return (NS_LDAP_MEMORY
);
2964 /* Error check the data and add the attributes */
2966 rc
= __s_add_attr(e
, "nisPublickey", ptr
->pubkey
);
2967 if (rc
!= NS_LDAP_SUCCESS
) {
2968 __s_cvt_freeEntryRdn(entry
, rdn
);
2972 rc
= __s_add_attr(e
, "nisSecretkey", ptr
->privkey
);
2973 if (rc
!= NS_LDAP_SUCCESS
) {
2974 __s_cvt_freeEntryRdn(entry
, rdn
);
2978 return (NS_LDAP_SUCCESS
);
2981 * Conversion: aliases
2982 * Input format: struct _ns_alias
2983 * Exported objectclass: mailGroup
2986 __s_cvt_aliases(const void *data
, char **rdn
,
2987 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
2992 /* routine specific */
2993 struct _ns_alias
*ptr
;
2997 static char *oclist
[] = {
3003 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3004 return (NS_LDAP_OP_FAILED
);
3005 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3007 return (NS_LDAP_MEMORY
);
3009 /* Convert the structure */
3010 ptr
= (struct _ns_alias
*)data
;
3012 if (ptr
->alias
== NULL
|| *ptr
->alias
== '\0') {
3013 __ns_ldap_freeEntry(e
);
3015 return (NS_LDAP_INVALID_PARAM
);
3018 /* Create an appropriate rdn */
3019 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->alias
);
3020 *rdn
= strdup(trdn
);
3022 __ns_ldap_freeEntry(e
);
3024 return (NS_LDAP_MEMORY
);
3027 rc
= __s_add_attr(e
, "mail", (char *)ptr
->alias
);
3028 if (rc
!= NS_LDAP_SUCCESS
) {
3029 __s_cvt_freeEntryRdn(entry
, rdn
);
3033 /* Error check the data and add the attributes */
3034 if (ptr
->member
&& ptr
->member
[0]) {
3036 for (i
= 0; *nm
; i
++, nm
++)
3038 nm
= (char **)calloc(i
+2, sizeof (char *));
3040 __s_cvt_freeEntryRdn(entry
, rdn
);
3041 return (NS_LDAP_MEMORY
);
3043 for (j
= 0; j
< i
; j
++)
3044 nm
[j
] = ptr
->member
[j
];
3046 rc
= __s_add_attrlist(e
, "mgrpRFC822MailMember", nm
);
3049 if (rc
!= NS_LDAP_SUCCESS
) {
3050 __s_cvt_freeEntryRdn(entry
, rdn
);
3055 return (NS_LDAP_SUCCESS
);
3059 * Conversion: automount
3060 * Input format: struct _ns_automount
3061 * Exported objectclass: automount
3064 __s_cvt_auto_mount(const void *data
, char **rdn
,
3065 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3070 /* routine specific */
3071 struct _ns_automount
*ptr
;
3073 void **paramVal
= NULL
;
3074 char **mappedschema
= NULL
;
3076 static char *oclist
[] = {
3082 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3083 return (NS_LDAP_OP_FAILED
);
3085 /* determine profile version number */
3086 rc
= __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P
, ¶mVal
, errorp
);
3087 if (paramVal
&& *paramVal
&&
3088 strcasecmp(*paramVal
, NS_LDAP_VERSION_1
) == 0)
3091 (void) __ns_ldap_freeParam(¶mVal
);
3093 (void) __ns_ldap_freeError(errorp
);
3095 /* use old schema for version 1 profiles */
3097 oclist
[0] = "nisObject";
3099 oclist
[0] = "automount";
3101 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3103 return (NS_LDAP_MEMORY
);
3105 /* Convert the structure */
3106 ptr
= (struct _ns_automount
*)data
;
3108 if (ptr
->key
== NULL
|| *ptr
->key
== '\0' || ptr
->value
== NULL
||
3109 ptr
->mapname
== NULL
) {
3110 __ns_ldap_freeEntry(e
);
3112 return (NS_LDAP_INVALID_PARAM
);
3115 /* Create an appropriate rdn */
3116 (void) snprintf(trdn
, RDNSIZE
, version1
? "cn=%s" : "automountKey=%s",
3118 *rdn
= strdup(trdn
);
3120 __ns_ldap_freeEntry(e
);
3122 return (NS_LDAP_MEMORY
);
3125 rc
= __s_add_attr(e
, version1
? "cn" : "automountKey",
3127 if (rc
!= NS_LDAP_SUCCESS
) {
3128 __s_cvt_freeEntryRdn(entry
, rdn
);
3132 rc
= __s_add_attr(e
, version1
? "nisMapEntry" : "automountInformation",
3133 (char *)ptr
->value
);
3134 if (rc
!= NS_LDAP_SUCCESS
) {
3135 __s_cvt_freeEntryRdn(entry
, rdn
);
3140 * even for version 2, if automount is mapped to nisObject we
3141 * still need 'nisMapName' attribute
3143 mappedschema
= __ns_ldap_getMappedObjectClass("automount", "automount");
3144 if (mappedschema
&& mappedschema
[0] &&
3145 strcasecmp(mappedschema
[0], "nisObject") == 0)
3148 __s_api_free2dArray(mappedschema
);
3151 rc
= __s_add_attr(e
, "nisMapName", (char *)ptr
->mapname
);
3152 if (rc
!= NS_LDAP_SUCCESS
) {
3153 __s_cvt_freeEntryRdn(entry
, rdn
);
3158 return (NS_LDAP_SUCCESS
);
3161 * Conversion: auth_attr
3162 * Input format: authstr_t
3163 * Exported objectclass: SolarisAuthAttr
3166 __s_cvt_authattr(const void *data
, char **rdn
,
3167 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3172 /* routine specific */
3175 static char *oclist
[] = {
3181 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3182 return (NS_LDAP_OP_FAILED
);
3184 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3186 return (NS_LDAP_MEMORY
);
3188 /* Convert the structure */
3189 ptr
= (authstr_t
*)data
;
3191 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' || ptr
->attr
== NULL
) {
3192 __ns_ldap_freeEntry(e
);
3194 return (NS_LDAP_INVALID_PARAM
);
3197 /* Create an appropriate rdn */
3198 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
3199 *rdn
= strdup(trdn
);
3201 __ns_ldap_freeEntry(e
);
3203 return (NS_LDAP_MEMORY
);
3206 rc
= __s_add_attr(e
, "cn", ptr
->name
);
3207 if (rc
!= NS_LDAP_SUCCESS
) {
3208 __s_cvt_freeEntryRdn(entry
, rdn
);
3212 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3213 if (rc
!= NS_LDAP_SUCCESS
) {
3214 __s_cvt_freeEntryRdn(entry
, rdn
);
3218 if (ptr
->res1
!= NULL
) {
3219 rc
= __s_add_attr(e
, "SolarisAttrReserved1", ptr
->res1
);
3220 if (rc
!= NS_LDAP_SUCCESS
) {
3221 __s_cvt_freeEntryRdn(entry
, rdn
);
3226 if (ptr
->res2
!= NULL
) {
3227 rc
= __s_add_attr(e
, "SolarisAttrReserved2", ptr
->res2
);
3228 if (rc
!= NS_LDAP_SUCCESS
) {
3229 __s_cvt_freeEntryRdn(entry
, rdn
);
3234 if (ptr
->short_desc
!= NULL
) {
3235 rc
= __s_add_attr(e
, "SolarisAttrShortDesc", ptr
->short_desc
);
3236 if (rc
!= NS_LDAP_SUCCESS
) {
3237 __s_cvt_freeEntryRdn(entry
, rdn
);
3242 if (ptr
->long_desc
!= NULL
) {
3243 rc
= __s_add_attr(e
, "SolarisAttrLongDesc", ptr
->long_desc
);
3244 if (rc
!= NS_LDAP_SUCCESS
) {
3245 __s_cvt_freeEntryRdn(entry
, rdn
);
3250 return (NS_LDAP_SUCCESS
);
3253 * Conversion: exec_attr
3254 * Input format: execstr_t
3255 * Exported objectclass: SolarisExecAttr
3258 __s_cvt_execattr(const void *data
, char **rdn
,
3259 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3264 char esc_str
[RDNSIZE
];
3265 /* routine specific */
3268 static char *oclist
[] = {
3275 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3276 return (NS_LDAP_OP_FAILED
);
3278 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3280 return (NS_LDAP_MEMORY
);
3282 /* Convert the structure */
3283 ptr
= (execstr_t
*)data
;
3285 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' ||
3286 ptr
->policy
== NULL
|| ptr
->policy
[0] == '\0' ||
3287 ptr
->type
== NULL
|| ptr
->type
[0] == '\0' ||
3288 ptr
->id
== NULL
|| ptr
->id
[0] == '\0') {
3289 __ns_ldap_freeEntry(e
);
3291 return (NS_LDAP_INVALID_PARAM
);
3295 * Escape special characters in ProfileID.
3297 if (escape_str(esc_str
, ptr
->id
) != 0) {
3298 __ns_ldap_freeEntry(e
);
3300 return (NS_LDAP_INVALID_PARAM
);
3303 /* Create an appropriate rdn */
3304 (void) snprintf(trdn
, RDNSIZE
, "cn=%s+SolarisKernelSecurityPolicy=%s"
3305 "+SolarisProfileType=%s+SolarisProfileId=%s",
3306 ptr
->name
, ptr
->policy
, ptr
->type
, esc_str
);
3308 *rdn
= strdup(trdn
);
3310 __ns_ldap_freeEntry(e
);
3312 return (NS_LDAP_MEMORY
);
3315 rc
= __s_add_attr(e
, "cn", ptr
->name
);
3316 if (rc
!= NS_LDAP_SUCCESS
) {
3317 __s_cvt_freeEntryRdn(entry
, rdn
);
3321 rc
= __s_add_attr(e
, "SolarisKernelSecurityPolicy", ptr
->policy
);
3322 if (rc
!= NS_LDAP_SUCCESS
) {
3323 __s_cvt_freeEntryRdn(entry
, rdn
);
3327 rc
= __s_add_attr(e
, "SolarisProfileType", ptr
->type
);
3328 if (rc
!= NS_LDAP_SUCCESS
) {
3329 __s_cvt_freeEntryRdn(entry
, rdn
);
3333 rc
= __s_add_attr(e
, "SolarisProfileId", ptr
->id
);
3334 if (rc
!= NS_LDAP_SUCCESS
) {
3335 __s_cvt_freeEntryRdn(entry
, rdn
);
3339 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3340 if (rc
!= NS_LDAP_SUCCESS
) {
3341 __s_cvt_freeEntryRdn(entry
, rdn
);
3345 if (ptr
->res1
!= NULL
) {
3346 rc
= __s_add_attr(e
, "SolarisAttrRes1", ptr
->res1
);
3347 if (rc
!= NS_LDAP_SUCCESS
) {
3348 __s_cvt_freeEntryRdn(entry
, rdn
);
3353 if (ptr
->res2
!= NULL
) {
3354 rc
= __s_add_attr(e
, "SolarisAttrRes2", ptr
->res2
);
3355 if (rc
!= NS_LDAP_SUCCESS
) {
3356 __s_cvt_freeEntryRdn(entry
, rdn
);
3361 return (NS_LDAP_SUCCESS
);
3364 * Conversion: prof_attr
3365 * Input format: profstr_t
3366 * Exported objectclass: SolarisProfAttr
3369 __s_cvt_profattr(const void *data
, char **rdn
,
3370 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3375 /* routine specific */
3378 static char *oclist
[] = {
3384 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3385 return (NS_LDAP_OP_FAILED
);
3387 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3389 return (NS_LDAP_MEMORY
);
3391 /* Convert the structure */
3392 ptr
= (profstr_t
*)data
;
3394 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' || ptr
->attr
== NULL
) {
3395 __ns_ldap_freeEntry(e
);
3397 return (NS_LDAP_INVALID_PARAM
);
3400 /* Create an appropriate rdn */
3401 (void) snprintf(trdn
, RDNSIZE
, "cn=%s", ptr
->name
);
3402 *rdn
= strdup(trdn
);
3404 __ns_ldap_freeEntry(e
);
3406 return (NS_LDAP_MEMORY
);
3409 rc
= __s_add_attr(e
, "cn", ptr
->name
);
3410 if (rc
!= NS_LDAP_SUCCESS
) {
3411 __s_cvt_freeEntryRdn(entry
, rdn
);
3415 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3416 if (rc
!= NS_LDAP_SUCCESS
) {
3417 __s_cvt_freeEntryRdn(entry
, rdn
);
3421 if (ptr
->res1
!= NULL
) {
3422 rc
= __s_add_attr(e
, "SolarisAttrReserved1", ptr
->res1
);
3423 if (rc
!= NS_LDAP_SUCCESS
) {
3424 __s_cvt_freeEntryRdn(entry
, rdn
);
3429 if (ptr
->res2
!= NULL
) {
3430 rc
= __s_add_attr(e
, "SolarisAttrReserved2", ptr
->res2
);
3431 if (rc
!= NS_LDAP_SUCCESS
) {
3432 __s_cvt_freeEntryRdn(entry
, rdn
);
3437 if (ptr
->desc
!= NULL
) {
3438 rc
= __s_add_attr(e
, "SolarisAttrLongDesc", ptr
->desc
);
3439 if (rc
!= NS_LDAP_SUCCESS
) {
3440 __s_cvt_freeEntryRdn(entry
, rdn
);
3445 return (NS_LDAP_SUCCESS
);
3448 * Conversion: user_attr
3449 * Input format: userstr_t
3450 * Exported objectclass: SolarisUserAttr
3453 __s_cvt_userattr(const void *data
, char **rdn
,
3454 ns_ldap_entry_t
**entry
, ns_ldap_error_t
**errorp
)
3459 /* routine specific */
3462 static char *oclist
[] = {
3467 if (data
== NULL
|| rdn
== NULL
|| entry
== NULL
|| errorp
== NULL
)
3468 return (NS_LDAP_OP_FAILED
);
3470 *entry
= e
= __s_mk_entry(oclist
, max_attr
);
3472 return (NS_LDAP_MEMORY
);
3474 /* Convert the structure */
3475 ptr
= (userstr_t
*)data
;
3477 if (ptr
->name
== NULL
|| ptr
->name
[0] == '\0' ||
3478 ptr
->attr
== NULL
) {
3479 __ns_ldap_freeEntry(e
);
3481 return (NS_LDAP_INVALID_PARAM
);
3484 /* Create an appropriate rdn */
3485 (void) snprintf(trdn
, RDNSIZE
, "uid=%s", ptr
->name
);
3486 *rdn
= strdup(trdn
);
3488 __ns_ldap_freeEntry(e
);
3490 return (NS_LDAP_MEMORY
);
3494 * SolarisUserAttr has no uid attribute
3497 rc
= __s_add_attr(e
, "SolarisAttrKeyValue", ptr
->attr
);
3498 if (rc
!= NS_LDAP_SUCCESS
) {
3499 __s_cvt_freeEntryRdn(entry
, rdn
);
3503 if (ptr
->qualifier
!= NULL
) {
3504 rc
= __s_add_attr(e
, "SolarisUserQualifier", ptr
->qualifier
);
3505 if (rc
!= NS_LDAP_SUCCESS
) {
3506 __s_cvt_freeEntryRdn(entry
, rdn
);
3511 if (ptr
->res1
!= NULL
) {
3512 rc
= __s_add_attr(e
, "SolarisAttrReserved1", ptr
->res1
);
3513 if (rc
!= NS_LDAP_SUCCESS
) {
3514 __s_cvt_freeEntryRdn(entry
, rdn
);
3519 if (ptr
->res2
!= NULL
) {
3520 rc
= __s_add_attr(e
, "SolarisAttrReserved2", ptr
->res2
);
3521 if (rc
!= NS_LDAP_SUCCESS
) {
3522 __s_cvt_freeEntryRdn(entry
, rdn
);
3527 return (NS_LDAP_SUCCESS
);
3530 * Add Typed Entry Conversion data structures
3533 typedef struct __ns_cvt_type
{
3534 const char *service
;
3536 #define AE 1 /* alway add entries */
3537 int (*cvt_rtn
)(const void *data
,
3539 ns_ldap_entry_t
**entry
,
3540 ns_ldap_error_t
**errorp
);
3543 static __ns_cvt_type_t __s_cvtlist
[] = {
3544 { NS_LDAP_TYPE_PASSWD
, 0, __s_cvt_passwd
},
3545 { NS_LDAP_TYPE_GROUP
, 0, __s_cvt_group
},
3546 { NS_LDAP_TYPE_HOSTS
, 0, __s_cvt_hosts
},
3547 { NS_LDAP_TYPE_IPNODES
, 0, __s_cvt_hosts
},
3548 { NS_LDAP_TYPE_RPC
, 0, __s_cvt_rpc
},
3549 { NS_LDAP_TYPE_PROTOCOLS
, 0, __s_cvt_protocols
},
3550 { NS_LDAP_TYPE_NETWORKS
, 0, __s_cvt_networks
},
3551 { NS_LDAP_TYPE_NETGROUP
, 0, __s_cvt_netgroups
},
3552 { NS_LDAP_TYPE_ALIASES
, 0, __s_cvt_aliases
},
3553 { NS_LDAP_TYPE_SERVICES
, 0, __s_cvt_services
},
3554 { NS_LDAP_TYPE_ETHERS
, 0, __s_cvt_ethers
},
3555 { NS_LDAP_TYPE_SHADOW
, 0, __s_cvt_shadow
},
3556 { NS_LDAP_TYPE_NETMASKS
, 0, __s_cvt_netmasks
},
3557 { NS_LDAP_TYPE_BOOTPARAMS
, 0, __s_cvt_bootparams
},
3558 { NS_LDAP_TYPE_AUTHATTR
, 0, __s_cvt_authattr
},
3559 { NS_LDAP_TYPE_EXECATTR
, 0, __s_cvt_execattr
},
3560 { NS_LDAP_TYPE_PROFILE
, 0, __s_cvt_profattr
},
3561 { NS_LDAP_TYPE_USERATTR
, AE
, __s_cvt_userattr
},
3562 { NS_LDAP_TYPE_AUTOMOUNT
, 0, __s_cvt_auto_mount
},
3563 { NS_LDAP_TYPE_PUBLICKEY
, AE
, __s_cvt_publickey
},
3564 { NS_LDAP_TYPE_PROJECT
, 0, __s_cvt_project
},
3569 * Add Typed Entry Routine
3573 int __ns_ldap_addTypedEntry(
3574 const char *servicetype
,
3578 const ns_cred_t
*cred
,
3580 ns_ldap_error_t
**errorp
)
3582 char *rdn
= NULL
, *fulldn
= NULL
;
3583 void **paramVal
= NULL
;
3584 ns_ldap_entry_t
*entry
= NULL
;
3585 const ns_ldap_attr_t
*const *modattrlist
;
3586 ns_ldap_search_desc_t
**sdlist
;
3589 char service
[BUFSIZE
];
3594 rc
= NS_LDAP_OP_FAILED
;
3595 for (s
= 0; __s_cvtlist
[s
].service
!= NULL
; s
++) {
3596 if (__s_cvtlist
[s
].cvt_rtn
== NULL
)
3598 if (strcasecmp(__s_cvtlist
[s
].service
, servicetype
) == 0)
3600 /* Or, check if the servicetype is auto_ */
3601 if (strcmp(__s_cvtlist
[s
].service
,
3602 NS_LDAP_TYPE_AUTOMOUNT
) == 0 &&
3603 strncasecmp(servicetype
, NS_LDAP_TYPE_AUTOMOUNT
,
3604 sizeof (NS_LDAP_TYPE_AUTOMOUNT
) - 1) == 0) {
3609 if (__s_cvtlist
[s
].service
== NULL
)
3612 /* Convert the data */
3613 rc
= (*__s_cvtlist
[s
].cvt_rtn
)(data
, &rdn
, &entry
, errorp
);
3614 if (rc
!= NS_LDAP_SUCCESS
) {
3615 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3619 __ns_ldap_freeEntry(entry
);
3620 return (NS_LDAP_OP_FAILED
);
3623 if (strcmp(servicetype
, "publickey") == 0) {
3624 struct _ns_pubkey
*ptr
;
3625 ptr
= (struct _ns_pubkey
*)data
;
3626 if (ptr
->hostcred
== NS_HOSTCRED_TRUE
)
3627 (void) strcpy(service
, "hosts");
3629 (void) strcpy(service
, "passwd");
3631 (void) strcpy(service
, servicetype
);
3633 /* Create the Full DN */
3634 if (basedn
== NULL
) {
3635 rc
= __s_api_get_SSD_from_SSDtoUse_service(service
,
3637 if (rc
!= NS_LDAP_SUCCESS
) {
3638 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3642 if (sdlist
== NULL
) {
3643 rc
= __s_api_getDNs(&dns
, service
, errorp
);
3644 if (rc
!= NS_LDAP_SUCCESS
) {
3646 __s_api_free2dArray(dns
);
3649 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3652 (void) snprintf(trdn
, RDNSIZE
, "%s,%s", rdn
, dns
[0]);
3653 __s_api_free2dArray(dns
);
3655 if (sdlist
[0]->basedn
) {
3656 (void) snprintf(trdn
, RDNSIZE
, "%s,%s",
3657 rdn
, sdlist
[0]->basedn
);
3659 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3660 return (NS_LDAP_OP_FAILED
);
3663 i
= strlen(trdn
) - 1;
3664 if (trdn
[i
] == COMMATOK
) {
3665 rc
= __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P
,
3667 if (rc
!= NS_LDAP_SUCCESS
) {
3668 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3671 i
= strlen(trdn
) + strlen((char *)(paramVal
[0])) + 1;
3672 fulldn
= (char *)calloc(i
, 1);
3673 if (fulldn
== NULL
) {
3674 (void) __ns_ldap_freeParam(¶mVal
);
3675 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3676 return (NS_LDAP_MEMORY
);
3678 (void) snprintf(fulldn
, i
, "%s%s", trdn
,
3679 (char *)(paramVal
[0]));
3680 (void) __ns_ldap_freeParam(¶mVal
);
3682 fulldn
= strdup(trdn
);
3683 if (fulldn
== NULL
) {
3684 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3685 return (NS_LDAP_MEMORY
);
3689 i
= strlen(rdn
) + strlen(basedn
) + 2;
3690 fulldn
= (char *)calloc(i
, 1);
3691 if (fulldn
== NULL
) {
3692 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3693 return (NS_LDAP_MEMORY
);
3695 (void) snprintf(fulldn
, i
, "%s,%s", rdn
, basedn
);
3698 modattrlist
= (const ns_ldap_attr_t
* const *)entry
->attr_pair
;
3699 /* Check to see if the entry exists already */
3700 /* May need to delete or update first */
3703 /* Modify the entry */
3705 * To add a shadow-like entry, the addTypedEntry function
3706 * would call __ns_ldap_repAttr first, and if server says
3707 * LDAP_NO_SUCH_OBJECT, then it tries __ns_ldap_addEntry.
3708 * This is to allow a netmask entry to be added even if the
3709 * base network entry is not in the directory. It would work
3710 * because the difference between the schema for the network
3711 * and netmask data contains only MAY attributes.
3713 * But for shadow data, the attributes do not have MUST
3714 * attributes the base entry needs, so if the __ns_ldap_addEntry
3715 * is executed, it would fail. The real reason, however, is that
3716 * the base entry did not exist. So returning
3717 * LDAP_OBJECT_CLASS_VIOLATION would just confused.
3719 if ((__s_cvtlist
[s
].flags
& AE
) != 0)
3720 rc
= __ns_ldap_addAttr(service
, fulldn
, modattrlist
,
3721 cred
, flags
, errorp
);
3723 rc
= __ns_ldap_repAttr(service
, fulldn
, modattrlist
,
3724 cred
, flags
, errorp
);
3725 if (rc
== NS_LDAP_INTERNAL
&& *errorp
&&
3726 (*errorp
)->status
== LDAP_NO_SUCH_OBJECT
) {
3727 (void) __ns_ldap_freeError(errorp
);
3728 rc
= __ns_ldap_addEntry(service
, fulldn
,
3729 entry
, cred
, flags
, errorp
);
3730 if (rc
== NS_LDAP_INTERNAL
&& *errorp
&&
3731 (*errorp
)->status
==
3732 LDAP_OBJECT_CLASS_VIOLATION
)
3733 (*errorp
)->status
= LDAP_NO_SUCH_OBJECT
;
3738 rc
= __ns_ldap_addEntry(service
, fulldn
, entry
,
3739 cred
, flags
, errorp
);
3740 if (rc
== NS_LDAP_INTERNAL
&& *errorp
&&
3741 (*errorp
)->status
== LDAP_ALREADY_EXISTS
&&
3742 ((strcmp(service
, "ethers") == 0) ||
3743 (strcmp(service
, "bootparams") == 0))) {
3744 rc
= modify_ethers_bootp(service
, rdn
, fulldn
,
3745 modattrlist
, cred
, flags
, errorp
);
3749 /* Free up entry created by conversion routine */
3751 __s_cvt_freeEntryRdn(&entry
, &rdn
);
3757 * Append the default base dn to the dn
3758 * when it ends with ','.
3760 * SSD = service:ou=foo,
3763 __s_api_append_default_basedn(const char *dn
, char **new_dn
, int *allocated
,
3764 ns_ldap_error_t
**errp
)
3767 int rc
= NS_LDAP_SUCCESS
, len
= 0;
3768 void **param
= NULL
;
3775 return (NS_LDAP_INVALID_PARAM
);
3777 rc
= __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P
,
3778 (void ***)¶m
, errp
);
3780 if (rc
!= NS_LDAP_SUCCESS
) {
3782 (void) __ns_ldap_freeParam(¶m
);
3787 str
= ((char **)param
)[0];
3788 len
= len
+ strlen(str
) +1;
3789 *new_dn
= (char *)malloc(len
);
3790 if (*new_dn
== NULL
) {
3791 (void) __ns_ldap_freeParam(¶m
);
3792 return (NS_LDAP_MEMORY
);
3796 (void) strcpy(*new_dn
, dn
);
3797 (void) strcat(*new_dn
, str
);
3799 (void) __ns_ldap_freeParam(¶m
);
3800 return (NS_LDAP_SUCCESS
);
3804 * Flatten the input ns_ldap_attr_t list, 'attr', and convert it into an
3805 * ldap_strlist_t structure in buffer 'buf', to be used by ldap_cachemgr.
3806 * The output contains a count, a list of offsets, which show where the
3807 * corresponding copied attribute type and attribute value are located.
3808 * For example, for dn=aaaa, userpassword=bbbb, shadowlastchange=cccc,
3809 * the output is the ldap_strlist_t structure with: ldap_count = 6,
3810 * (buf + ldap_offsets[0]) -> "dn"
3811 * (buf + ldap_offsets[1]) -> "aaaa"
3812 * (buf + ldap_offsets[2]) -> "userPassword"
3813 * (buf + ldap_offsets[3]) -> "bbbb"
3814 * (buf + ldap_offsets[4]) -> "shadowlastchange"
3815 * (buf + ldap_offsets[5]) -> "cccc"
3816 * and all the string data shown above copied into the buffer after
3817 * the offset array. The total length of the data will be the return
3818 * value, or -1 if error.
3821 attr2list(const char *dn
, ns_ldap_attr_t
**attr
,
3822 char *buf
, int bufsize
)
3827 ldap_strlist_t
*al
= (ldap_strlist_t
*)buf
;
3828 ns_ldap_attr_t
*a
= (ns_ldap_attr_t
*)*attr
;
3829 ns_ldap_attr_t
**aptr
= (ns_ldap_attr_t
**)attr
;
3831 /* bufsize > strlen(dn) + strlen("dn") + 1 ('\0') */
3832 if ((strlen(dn
) + 2 + 1) >= bufsize
)
3835 /* count number of attributes */
3838 al
->ldap_count
= 2 + c
* 2;
3839 ao
= sizeof (al
->ldap_count
) + sizeof (al
->ldap_offsets
[0]) *
3843 al
->ldap_offsets
[0] = ao
;
3850 (void) strlcpy(ap
, "dn", bufsize
);
3853 al
->ldap_offsets
[1] = ao
;
3854 ao
+= strlen(dn
) + 1;
3857 (void) strlcpy(ap
, dn
, bufsize
);
3861 for (c
= 2; c
< al
->ldap_count
; c
++, aptr
++) {
3863 if (a
->attrname
== NULL
|| a
->attrvalue
== NULL
||
3864 a
->value_count
!= 1 || a
->attrvalue
[0] == NULL
)
3866 al
->ldap_offsets
[c
] = ao
;
3867 ao
+= strlen(a
->attrname
) + 1;
3870 (void) strlcpy(ap
, a
->attrname
, bufsize
);
3874 al
->ldap_offsets
[c
] = ao
;
3875 ao
+= strlen(a
->attrvalue
[0]) + 1;
3876 (void) strlcpy(ap
, a
->attrvalue
[0], bufsize
);
3884 * Send a modify request to the ldap_cachemgr daemon
3885 * which will use the admin credential to perform the
3892 ns_ldap_attr_t
**attr
,
3893 ns_ldap_error_t
**errorp
)
3897 char s_b
[DOORBUFFERSIZE
];
3905 char errstr
[MAXERROR
];
3906 ldap_admin_mod_result_t
*admin_result
;
3909 (void) memset(space
.s_b
, 0, DOORBUFFERSIZE
);
3910 len
= attr2list(dn
, attr
, (char *)&space
.s_d
.ldap_call
.ldap_u
.strlist
,
3911 sizeof (space
) - offsetof(ldap_return_t
, ldap_u
));
3913 return (NS_LDAP_INVALID_PARAM
);
3915 adata
= sizeof (ldap_call_t
) + len
;
3916 ndata
= sizeof (space
);
3917 space
.s_d
.ldap_call
.ldap_callnumber
= ADMINMODIFY
;
3920 switch (__ns_ldap_trydoorcall(&sptr
, &ndata
, &adata
)) {
3921 case NS_CACHE_SUCCESS
:
3923 case NS_CACHE_NOTFOUND
:
3924 (void) snprintf(errstr
, sizeof (errstr
),
3925 gettext("Door call ADMINMODIFY to "
3926 "ldap_cachemgr failed - error: %d"),
3927 space
.s_d
.ldap_ret
.ldap_errno
);
3928 MKERROR(LOG_WARNING
, *errorp
, NS_CONFIG_CACHEMGR
,
3930 return (NS_LDAP_OP_FAILED
);
3932 return (NS_LDAP_OP_FAILED
);
3935 admin_result
= &sptr
->ldap_ret
.ldap_u
.admin_result
;
3936 if (admin_result
->ns_err
== NS_LDAP_SUCCESS
)
3937 rc
= NS_LDAP_SUCCESS
;
3939 rc
= admin_result
->ns_err
;
3940 if (admin_result
->msg_size
== 0)
3941 *errorp
= __s_api_make_error(admin_result
->status
,
3944 *errorp
= __s_api_make_error(admin_result
->status
,
3948 /* clean up the door call */
3949 if (sptr
!= &space
.s_d
) {
3950 (void) munmap((char *)sptr
, ndata
);