2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * DESCRIPTION: This is the N2L equivalent of changepasswd.c. The traditional
30 * version modifies the NIS source files and then initiates a
31 * ypmake to make the maps and push them.
32 *
33 * For N2L there are no source files and the policy is that the
34 * definitive information is that contained in the DIT. Old
35 * information is read from LDAP. Assuming this authenticates, and
36 * the change is acceptable, this information is modified and
37 * written back to LDAP.
38 *
39 * Related map entries are then found and updated finally
40 * yppushes of the changed maps are initiated. Since the
41 * definitive information has already correctly been updated the
42 * code is tolerant of some errors during this operation.
43 *
44 * What was previously in the maps is irrelevant.
45 *
46 * Some less than perfect code (like inline constants for
47 * return values and a few globals) is retained from the original.
53 #include <unistd.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <stdio.h>
57 #include <errno.h>
58 #include <syslog.h>
59 #include <pwd.h>
60 #include <signal.h>
61 #include <crypt.h>
62 #include <rpc/rpc.h>
63 #include <rpcsvc/yppasswd.h>
64 #include <utmpx.h>
65 #include <shadow.h>
66
67 #include <ndbm.h>
68 /* DO NOT INCLUDE SHIM_HOOKS.H */
69 #include "shim.h"
70 #include "yptol.h"
71 #include "../ldap_util.h"
72
73 /* Constants */
74 #define CRYPTPWSIZE CRYPT_MAXCIPHERTEXTLEN
75 #define STRSIZE 100
76 #define FINGERSIZE (4 * STRSIZE - 4)
77 #define SHELLSIZE (STRSIZE - 2)
78
79 #define UTUSERLEN (sizeof (((struct utmpx *)0)->ut_user))
80 #define COLON_CHAR ':'
81
82 /*
83 * Path to DBM files. This is only required for N2L mode. Traditional mode
84 * works with the source files and uses the NIS Makefile to generate the maps.
85 * Seems to be hard coded in the rest of NIS so same is done here.
86 */
87 #define YPDBPATH "/var/yp"
88
89 /* Names of password and adjunct mappings. Used to access DIT */
90 #define BYNAME ".byname"
91 #define BYUID ".byuid"
92 #define BYGID ".bygid"
416 *
417 * DESCRIPTION: Finds entries in one list of map that need to be updated.
418 * updates them and writes them back.
419 *
420 * INPUTS: Null terminated list of maps to process.
421 * Domain name
422 * Information to write (including user name)
423 * Flag indicating if this is the adjunct list
424 *
425 * OUTPUTS: An error code
426 */
427 int
428 proc_map_list(char **map_list, char *domain,
429 struct passwd_entry *pwd, bool_t adjunct_flag)
430 {
431 char *myself = "proc_map_list";
432 char *map_name;
433 char cmdbuf[BUFSIZ];
434 int map_name_len = 0;
435 int index, ans = 0;
436 int res;
437
438 /* If this is a adjunct list check LDAP had some adjunct info */
439 if ((adjunct_flag) && (!pwd->adjunct)) {
440 logmsg(MSG_NOTIMECHECK, LOG_INFO,
441 "Have adjunct map list but no adjunct data in DIT");
442 /* Not a disaster */
443 return (0);
444 }
445
446 /* Allocate enough buffer to take longest map name */
447 for (index = 0; map_list[index] != NULL; index ++)
448 if (map_name_len < strlen(map_list[index]))
449 map_name_len = strlen(map_list[index]);
450 map_name_len += strlen(YPDBPATH);
451 map_name_len += strlen(NTOL_PREFIX);
452 map_name_len += strlen(domain);
453 map_name_len += 3;
454 if (NULL == (map_name = am(myself, map_name_len))) {
455 logmsg(MSG_NOMEM, LOG_ERR, "Could not alloc map name");
456 return (2);
1037 * FUNCTION: get_old_info()
1038 *
1039 * DESCRIPTION: Gets as much information as possible from LDAP about one user.
1040 *
1041 * This goes through the mapping system. This is messy because
1042 * them mapping system will build up a password entry from the
1043 * contents of the DIT. We then have to parse this to recover
1044 * it's individual fields.
1045 *
1046 * INPUT: Pointer to user name
1047 * Domain
1048 *
1049 * OUTPUT: The info in malloced space. To be freed by caller.
1050 * NULL on failure.
1051 */
1052 struct passwd_entry *
1053 get_old_info(char *name, char *domain)
1054 {
1055 char *myself = "get_old_info";
1056 struct passwd_entry *old_passwd;
1057 char *p;
1058 datum key, data;
1059 suc_code res;
1060
1061 /* Get the password entry */
1062 key.dptr = name;
1063 key.dsize = strlen(key.dptr);
1064 read_from_dit(PASSWD_MAPPING, domain, &key, &data);
1065 if (NULL == data.dptr) {
1066 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1067 "Could not read old pwd for %s", name);
1068 return (NULL);
1069 }
1070
1071 /* Pull password apart */
1072 old_passwd = am(myself, sizeof (struct passwd_entry));
1073 if (NULL == old_passwd) {
1074 logmsg(MSG_NOMEM, LOG_ERR, "Could not alloc for pwd decode");
1075 sfree(data.dptr);
1076 return (NULL);
1077 }
|
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2015 Gary Mills
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * DESCRIPTION: This is the N2L equivalent of changepasswd.c. The traditional
29 * version modifies the NIS source files and then initiates a
30 * ypmake to make the maps and push them.
31 *
32 * For N2L there are no source files and the policy is that the
33 * definitive information is that contained in the DIT. Old
34 * information is read from LDAP. Assuming this authenticates, and
35 * the change is acceptable, this information is modified and
36 * written back to LDAP.
37 *
38 * Related map entries are then found and updated finally
39 * yppushes of the changed maps are initiated. Since the
40 * definitive information has already correctly been updated the
41 * code is tolerant of some errors during this operation.
42 *
43 * What was previously in the maps is irrelevant.
44 *
45 * Some less than perfect code (like inline constants for
46 * return values and a few globals) is retained from the original.
52 #include <unistd.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <stdio.h>
56 #include <errno.h>
57 #include <syslog.h>
58 #include <pwd.h>
59 #include <signal.h>
60 #include <crypt.h>
61 #include <rpc/rpc.h>
62 #include <rpcsvc/yppasswd.h>
63 #include <utmpx.h>
64 #include <shadow.h>
65
66 #include <ndbm.h>
67 /* DO NOT INCLUDE SHIM_HOOKS.H */
68 #include "shim.h"
69 #include "yptol.h"
70 #include "../ldap_util.h"
71
72 /*
73 * Undocumented external function in libnsl
74 */
75 extern int getdomainname(char *, int);
76
77 /* Constants */
78 #define CRYPTPWSIZE CRYPT_MAXCIPHERTEXTLEN
79 #define STRSIZE 100
80 #define FINGERSIZE (4 * STRSIZE - 4)
81 #define SHELLSIZE (STRSIZE - 2)
82
83 #define UTUSERLEN (sizeof (((struct utmpx *)0)->ut_user))
84 #define COLON_CHAR ':'
85
86 /*
87 * Path to DBM files. This is only required for N2L mode. Traditional mode
88 * works with the source files and uses the NIS Makefile to generate the maps.
89 * Seems to be hard coded in the rest of NIS so same is done here.
90 */
91 #define YPDBPATH "/var/yp"
92
93 /* Names of password and adjunct mappings. Used to access DIT */
94 #define BYNAME ".byname"
95 #define BYUID ".byuid"
96 #define BYGID ".bygid"
420 *
421 * DESCRIPTION: Finds entries in one list of map that need to be updated.
422 * updates them and writes them back.
423 *
424 * INPUTS: Null terminated list of maps to process.
425 * Domain name
426 * Information to write (including user name)
427 * Flag indicating if this is the adjunct list
428 *
429 * OUTPUTS: An error code
430 */
431 int
432 proc_map_list(char **map_list, char *domain,
433 struct passwd_entry *pwd, bool_t adjunct_flag)
434 {
435 char *myself = "proc_map_list";
436 char *map_name;
437 char cmdbuf[BUFSIZ];
438 int map_name_len = 0;
439 int index, ans = 0;
440
441 /* If this is a adjunct list check LDAP had some adjunct info */
442 if ((adjunct_flag) && (!pwd->adjunct)) {
443 logmsg(MSG_NOTIMECHECK, LOG_INFO,
444 "Have adjunct map list but no adjunct data in DIT");
445 /* Not a disaster */
446 return (0);
447 }
448
449 /* Allocate enough buffer to take longest map name */
450 for (index = 0; map_list[index] != NULL; index ++)
451 if (map_name_len < strlen(map_list[index]))
452 map_name_len = strlen(map_list[index]);
453 map_name_len += strlen(YPDBPATH);
454 map_name_len += strlen(NTOL_PREFIX);
455 map_name_len += strlen(domain);
456 map_name_len += 3;
457 if (NULL == (map_name = am(myself, map_name_len))) {
458 logmsg(MSG_NOMEM, LOG_ERR, "Could not alloc map name");
459 return (2);
1040 * FUNCTION: get_old_info()
1041 *
1042 * DESCRIPTION: Gets as much information as possible from LDAP about one user.
1043 *
1044 * This goes through the mapping system. This is messy because
1045 * them mapping system will build up a password entry from the
1046 * contents of the DIT. We then have to parse this to recover
1047 * it's individual fields.
1048 *
1049 * INPUT: Pointer to user name
1050 * Domain
1051 *
1052 * OUTPUT: The info in malloced space. To be freed by caller.
1053 * NULL on failure.
1054 */
1055 struct passwd_entry *
1056 get_old_info(char *name, char *domain)
1057 {
1058 char *myself = "get_old_info";
1059 struct passwd_entry *old_passwd;
1060 datum key, data;
1061 suc_code res;
1062
1063 /* Get the password entry */
1064 key.dptr = name;
1065 key.dsize = strlen(key.dptr);
1066 read_from_dit(PASSWD_MAPPING, domain, &key, &data);
1067 if (NULL == data.dptr) {
1068 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1069 "Could not read old pwd for %s", name);
1070 return (NULL);
1071 }
1072
1073 /* Pull password apart */
1074 old_passwd = am(myself, sizeof (struct passwd_entry));
1075 if (NULL == old_passwd) {
1076 logmsg(MSG_NOMEM, LOG_ERR, "Could not alloc for pwd decode");
1077 sfree(data.dptr);
1078 return (NULL);
1079 }
|