passwd.c (dd1104fbe0f0f41434502f335b9f0b34999f771c) passwd.c (36e852a172cba914383d7341c988128b2c667fbd)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 177 unchanged lines hidden (view full) ---

186
187static pam_repository_t auth_rep;
188static pwu_repository_t repository;
189static pwu_repository_t __REPFILES = { "files", NULL, 0 };
190
191/*
192 * Function Declarations
193 */
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 177 unchanged lines hidden (view full) ---

186
187static pam_repository_t auth_rep;
188static pwu_repository_t repository;
189static pwu_repository_t __REPFILES = { "files", NULL, 0 };
190
191/*
192 * Function Declarations
193 */
194extern nis_name nis_local_directory(void);
195
196extern void setusershell(void);
197extern char *getusershell(void);
198extern void endusershell(void);
199
200static void passwd_exit(int retcode) __NORETURN;
201static void rusage(void);
202static int ckuid(void);

--- 267 unchanged lines hidden (view full) ---

470 else
471 (void) printf(gettext(MSG_DIR_UNCHANGED));
472 break;
473 }
474
475 if (attributes != NULL) {
476 retval = __set_authtoken_attr(usrname,
477 pamh->ps_item[PAM_AUTHTOK].pi_addr,
194
195extern void setusershell(void);
196extern char *getusershell(void);
197extern void endusershell(void);
198
199static void passwd_exit(int retcode) __NORETURN;
200static void rusage(void);
201static int ckuid(void);

--- 267 unchanged lines hidden (view full) ---

469 else
470 (void) printf(gettext(MSG_DIR_UNCHANGED));
471 break;
472 }
473
474 if (attributes != NULL) {
475 retval = __set_authtoken_attr(usrname,
476 pamh->ps_item[PAM_AUTHTOK].pi_addr,
478 NULL, &repository, attributes, &updated_reps);
477 &repository, attributes, &updated_reps);
479 switch (retval) {
480 case PWU_SUCCESS:
481 for (i = 1; i <= REP_LAST; i <<= 1) {
482 if ((updated_reps & i) == 0)
483 continue;
484 (void) printf(gettext(MSG_SUCCESS),
485 prognamep, usrname);
486 }

--- 199 unchanged lines hidden (view full) ---

686{
687 extern char *optarg;
688 char *char_p;
689 int opt;
690 int flag;
691
692 flag = 0;
693
478 switch (retval) {
479 case PWU_SUCCESS:
480 for (i = 1; i <= REP_LAST; i <<= 1) {
481 if ((updated_reps & i) == 0)
482 continue;
483 (void) printf(gettext(MSG_SUCCESS),
484 prognamep, usrname);
485 }

--- 199 unchanged lines hidden (view full) ---

685{
686 extern char *optarg;
687 char *char_p;
688 int opt;
689 int flag;
690
691 flag = 0;
692
694 while ((opt = getopt(argc, argv, "r:aldefghsux:n:w:D:N")) != EOF) {
693 while ((opt = getopt(argc, argv, "r:aldefghsux:n:w:N")) != EOF) {
695 switch (opt) {
696
697 case 'r': /* Repository Specified */
698 /* repository: this option should be specified first */
699
700 if (repository.type != NULL) {
701 (void) fprintf(stderr, gettext(
702 "Repository is already defined or specified.\n"));
703 rusage();
704 retval = BADSYN;
705 return (FAIL);
706 }
694 switch (opt) {
695
696 case 'r': /* Repository Specified */
697 /* repository: this option should be specified first */
698
699 if (repository.type != NULL) {
700 (void) fprintf(stderr, gettext(
701 "Repository is already defined or specified.\n"));
702 rusage();
703 retval = BADSYN;
704 return (FAIL);
705 }
707 if (strcmp(optarg, "nisplus") == 0) {
706 if (strcmp(optarg, "nis") == 0) {
708 repository.type = optarg;
707 repository.type = optarg;
709 repository.scope = nis_local_directory();
710 if (repository.scope != NULL) {
711 repository.scope_len =
712 strlen(repository.scope)+ 1;
713 }
714 } else if (strcmp(optarg, "nis") == 0) {
715 repository.type = optarg;
716 } else if (strcmp(optarg, "ldap") == 0) {
717 repository.type = optarg;
718 } else if (strcmp(optarg, "files") == 0) {
719 repository.type = optarg;
720 } else {
721 (void) fprintf(stderr,
722 gettext("invalid repository: %s\n"),
723 optarg);

--- 37 unchanged lines hidden (view full) ---

761
762 case 'N': /* set account to be "no login" */
763
764 /* if no repository the default for -N is files */
765 if (repository.type == NULL)
766 repository = __REPFILES;
767
768 if (IS_FILES(repository) == FALSE &&
708 } else if (strcmp(optarg, "ldap") == 0) {
709 repository.type = optarg;
710 } else if (strcmp(optarg, "files") == 0) {
711 repository.type = optarg;
712 } else {
713 (void) fprintf(stderr,
714 gettext("invalid repository: %s\n"),
715 optarg);

--- 37 unchanged lines hidden (view full) ---

753
754 case 'N': /* set account to be "no login" */
755
756 /* if no repository the default for -N is files */
757 if (repository.type == NULL)
758 repository = __REPFILES;
759
760 if (IS_FILES(repository) == FALSE &&
769 IS_LDAP(repository) == FALSE &&
770 IS_NISPLUS(repository) == FALSE) {
761 IS_LDAP(repository) == FALSE) {
771 (void) fprintf(stderr, gettext(
762 (void) fprintf(stderr, gettext(
772 "-N only applies to files, ldap or "
773 "nisplus repository\n"));
763 "-N only applies to files or ldap "
764 "repository\n"));
774 rusage(); /* exit */
775 retval = BADOPT;
776 return (FAIL);
777 }
778
779 /*
780 * Only privileged processes can execute this
781 * for FILES or LDAP

--- 12 unchanged lines hidden (view full) ---

794
795 case 'l': /* lock the password */
796
797 /* if no repository the default for -l is files */
798 if (repository.type == NULL)
799 repository = __REPFILES;
800
801 if (IS_FILES(repository) == FALSE &&
765 rusage(); /* exit */
766 retval = BADOPT;
767 return (FAIL);
768 }
769
770 /*
771 * Only privileged processes can execute this
772 * for FILES or LDAP

--- 12 unchanged lines hidden (view full) ---

785
786 case 'l': /* lock the password */
787
788 /* if no repository the default for -l is files */
789 if (repository.type == NULL)
790 repository = __REPFILES;
791
792 if (IS_FILES(repository) == FALSE &&
802 IS_LDAP(repository) == FALSE &&
803 IS_NISPLUS(repository) == FALSE) {
793 IS_LDAP(repository) == FALSE) {
804 (void) fprintf(stderr, gettext(
794 (void) fprintf(stderr, gettext(
805 "-l only applies to files, ldap or "
806 "nisplus repository\n"));
795 "-l only applies to files or ldap "
796 "repository\n"));
807 rusage(); /* exit */
808 retval = BADOPT;
809 return (FAIL);
810 }
811
812 /*
813 * Only privileged processes can execute this
814 * for FILES or LDAP

--- 12 unchanged lines hidden (view full) ---

827
828 case 'u': /* unlock the password */
829
830 /* if no repository the default for -u is files */
831 if (repository.type == NULL)
832 repository = __REPFILES;
833
834 if (IS_FILES(repository) == FALSE &&
797 rusage(); /* exit */
798 retval = BADOPT;
799 return (FAIL);
800 }
801
802 /*
803 * Only privileged processes can execute this
804 * for FILES or LDAP

--- 12 unchanged lines hidden (view full) ---

817
818 case 'u': /* unlock the password */
819
820 /* if no repository the default for -u is files */
821 if (repository.type == NULL)
822 repository = __REPFILES;
823
824 if (IS_FILES(repository) == FALSE &&
835 IS_LDAP(repository) == FALSE &&
836 IS_NISPLUS(repository) == FALSE) {
825 IS_LDAP(repository) == FALSE) {
837 (void) fprintf(stderr, gettext(
826 (void) fprintf(stderr, gettext(
838 "-u only applies to files, ldap or "
839 "nisplus repository\n"));
827 "-u only applies to files or ldap "
828 "repository\n"));
840 rusage(); /* exit */
841 retval = BADOPT;
842 return (FAIL);
843 }
844
845 /*
846 * Only privileged processes can execute this
847 * for FILES or LDAP

--- 13 unchanged lines hidden (view full) ---

861
862 case 'x': /* set the max date */
863
864 /* if no repository the default for -x is files */
865 if (repository.type == NULL)
866 repository = __REPFILES;
867
868 if (IS_FILES(repository) == FALSE &&
829 rusage(); /* exit */
830 retval = BADOPT;
831 return (FAIL);
832 }
833
834 /*
835 * Only privileged processes can execute this
836 * for FILES or LDAP

--- 13 unchanged lines hidden (view full) ---

850
851 case 'x': /* set the max date */
852
853 /* if no repository the default for -x is files */
854 if (repository.type == NULL)
855 repository = __REPFILES;
856
857 if (IS_FILES(repository) == FALSE &&
869 IS_LDAP(repository) == FALSE &&
870 IS_NISPLUS(repository) == FALSE) {
858 IS_LDAP(repository) == FALSE) {
871 (void) fprintf(stderr, gettext(
859 (void) fprintf(stderr, gettext(
872 "-x only applies to files, ldap or "
873 "nisplus repository\n"));
860 "-x only applies to files or ldap "
861 "repository\n"));
874 rusage(); /* exit */
875 retval = BADSYN;
876 return (FAIL);
877 }
878
879 /*
880 * Only privileged process can execute this
881 * for FILES or LDAP

--- 21 unchanged lines hidden (view full) ---

903
904 case 'n': /* set the min date */
905
906 /* if no repository the default for -n is files */
907 if (repository.type == NULL)
908 repository = __REPFILES;
909
910 if (IS_FILES(repository) == FALSE &&
862 rusage(); /* exit */
863 retval = BADSYN;
864 return (FAIL);
865 }
866
867 /*
868 * Only privileged process can execute this
869 * for FILES or LDAP

--- 21 unchanged lines hidden (view full) ---

891
892 case 'n': /* set the min date */
893
894 /* if no repository the default for -n is files */
895 if (repository.type == NULL)
896 repository = __REPFILES;
897
898 if (IS_FILES(repository) == FALSE &&
911 IS_LDAP(repository) == FALSE &&
912 IS_NISPLUS(repository) == FALSE) {
899 IS_LDAP(repository) == FALSE) {
913 (void) fprintf(stderr, gettext(
900 (void) fprintf(stderr, gettext(
914 "-n only applies to files, ldap or "
915 "nisplus repository\n"));
901 "-n only applies to files or ldap "
902 "repository\n"));
916 rusage(); /* exit */
917 retval = BADSYN;
918 return (FAIL);
919 }
920
921 /*
922 * Only privileged process can execute this
923 * for FILES or LDAP

--- 19 unchanged lines hidden (view full) ---

943
944 case 'w': /* set the warning field */
945
946 /* if no repository the default for -w is files */
947 if (repository.type == NULL)
948 repository = __REPFILES;
949
950 if (IS_FILES(repository) == FALSE &&
903 rusage(); /* exit */
904 retval = BADSYN;
905 return (FAIL);
906 }
907
908 /*
909 * Only privileged process can execute this
910 * for FILES or LDAP

--- 19 unchanged lines hidden (view full) ---

930
931 case 'w': /* set the warning field */
932
933 /* if no repository the default for -w is files */
934 if (repository.type == NULL)
935 repository = __REPFILES;
936
937 if (IS_FILES(repository) == FALSE &&
951 IS_LDAP(repository) == FALSE &&
952 IS_NISPLUS(repository) == FALSE) {
938 IS_LDAP(repository) == FALSE) {
953 (void) fprintf(stderr, gettext(
939 (void) fprintf(stderr, gettext(
954 "-w only applies to files, ldap or "
955 "nisplus repository\n"));
940 "-w only applies to files or ldap "
941 "repository\n"));
956 rusage(); /* exit */
957 retval = BADSYN;
958 return (FAIL);
959 }
960
961 /*
962 * Only privileged process can execute this
963 * for FILES or LDAP

--- 23 unchanged lines hidden (view full) ---

987
988 /* if no repository the default for -s is files */
989 if (repository.type == NULL)
990 repository = __REPFILES;
991
992
993 /* display password attributes */
994 if (IS_FILES(repository) == FALSE &&
942 rusage(); /* exit */
943 retval = BADSYN;
944 return (FAIL);
945 }
946
947 /*
948 * Only privileged process can execute this
949 * for FILES or LDAP

--- 23 unchanged lines hidden (view full) ---

973
974 /* if no repository the default for -s is files */
975 if (repository.type == NULL)
976 repository = __REPFILES;
977
978
979 /* display password attributes */
980 if (IS_FILES(repository) == FALSE &&
995 IS_LDAP(repository) == FALSE &&
996 IS_NISPLUS(repository) == FALSE) {
981 IS_LDAP(repository) == FALSE) {
997 (void) fprintf(stderr, gettext(
982 (void) fprintf(stderr, gettext(
998 "-s only applies to files, ldap or "
999 "nisplus repository\n"));
983 "-s only applies to files or ldap "
984 "repository\n"));
1000 rusage(); /* exit */
1001 retval = BADSYN;
1002 return (FAIL);
1003 }
1004
1005 /*
1006 * Only privileged process can execute this
1007 * for FILES or LDAP

--- 10 unchanged lines hidden (view full) ---

1018
1019 case 'a': /* display password attributes */
1020
1021 /* if no repository the default for -a is files */
1022 if (repository.type == NULL)
1023 repository = __REPFILES;
1024
1025 if (IS_FILES(repository) == FALSE &&
985 rusage(); /* exit */
986 retval = BADSYN;
987 return (FAIL);
988 }
989
990 /*
991 * Only privileged process can execute this
992 * for FILES or LDAP

--- 10 unchanged lines hidden (view full) ---

1003
1004 case 'a': /* display password attributes */
1005
1006 /* if no repository the default for -a is files */
1007 if (repository.type == NULL)
1008 repository = __REPFILES;
1009
1010 if (IS_FILES(repository) == FALSE &&
1026 IS_LDAP(repository) == FALSE &&
1027 IS_NISPLUS(repository) == FALSE) {
1011 IS_LDAP(repository) == FALSE) {
1028 (void) fprintf(stderr, gettext(
1012 (void) fprintf(stderr, gettext(
1029 "-a only applies to files, ldap or "
1030 "nisplus repository\n"));
1013 "-a only applies to files or ldap "
1014 "repository\n"));
1031 rusage(); /* exit */
1032 retval = BADSYN;
1033 return (FAIL);
1034 }
1035
1036 /*
1037 * Only privileged process can execute this
1038 * for FILES or LDAP

--- 10 unchanged lines hidden (view full) ---

1049
1050 case 'f': /* expire password attributes */
1051
1052 /* if no repository the default for -f is files */
1053 if (repository.type == NULL)
1054 repository = __REPFILES;
1055
1056 if (IS_FILES(repository) == FALSE &&
1015 rusage(); /* exit */
1016 retval = BADSYN;
1017 return (FAIL);
1018 }
1019
1020 /*
1021 * Only privileged process can execute this
1022 * for FILES or LDAP

--- 10 unchanged lines hidden (view full) ---

1033
1034 case 'f': /* expire password attributes */
1035
1036 /* if no repository the default for -f is files */
1037 if (repository.type == NULL)
1038 repository = __REPFILES;
1039
1040 if (IS_FILES(repository) == FALSE &&
1057 IS_LDAP(repository) == FALSE &&
1058 IS_NISPLUS(repository) == FALSE) {
1041 IS_LDAP(repository) == FALSE) {
1059 (void) fprintf(stderr, gettext(
1042 (void) fprintf(stderr, gettext(
1060 "-f only applies to files, ldap or "
1061 "nisplus repository\n"));
1043 "-f only applies to files or ldap "
1044 "repository\n"));
1062 rusage(); /* exit */
1063 retval = BADSYN;
1064 return (FAIL);
1065 }
1066
1067 /*
1068 * Only privileged process can execute this
1069 * for FILES or LDAP

--- 4 unchanged lines hidden (view full) ---

1074 if (flag & (SAFLAG|FFLAG|NONAGEFLAG)) {
1075 retval = BADOPT;
1076 return (FAIL);
1077 }
1078 flag |= FFLAG;
1079 attrlist_add(attributes, ATTR_EXPIRE_PASSWORD, NULL);
1080 break;
1081
1045 rusage(); /* exit */
1046 retval = BADSYN;
1047 return (FAIL);
1048 }
1049
1050 /*
1051 * Only privileged process can execute this
1052 * for FILES or LDAP

--- 4 unchanged lines hidden (view full) ---

1057 if (flag & (SAFLAG|FFLAG|NONAGEFLAG)) {
1058 retval = BADOPT;
1059 return (FAIL);
1060 }
1061 flag |= FFLAG;
1062 attrlist_add(attributes, ATTR_EXPIRE_PASSWORD, NULL);
1063 break;
1064
1082 case 'D': /* domain name specified */
1083 if (IS_NISPLUS(repository) == FALSE) {
1084 (void) fprintf(stderr, gettext(
1085 "-D only applies to nisplus repository\n"));
1086 rusage(); /* exit */
1087 retval = BADSYN;
1088 return (FAIL);
1089 }
1090
1091 if (flag & AFLAG) {
1092 retval = BADOPT;
1093 return (FAIL);
1094 }
1095 /* It is cleaner not to set this flag */
1096 /* flag |= OFLAG; */
1097
1098 /* get domain from optarg */
1099 repository.scope = optarg;
1100 if (repository.scope != NULL) {
1101 repository.scope_len =
1102 strlen(repository.scope)+1;
1103 }
1104 break;
1105
1106 case 'e': /* change login shell */
1107
1108 /* if no repository the default for -e is files */
1109 if (repository.type == NULL)
1110 repository = __REPFILES;
1111
1112 /*
1113 * Only privileged process can execute this

--- 306 unchanged lines hidden (view full) ---

1420
1421/*
1422 * get_namelist_local
1423 *
1424 */
1425
1426/*
1427 * Our private version of the switch frontend for getspent. We want
1065 case 'e': /* change login shell */
1066
1067 /* if no repository the default for -e is files */
1068 if (repository.type == NULL)
1069 repository = __REPFILES;
1070
1071 /*
1072 * Only privileged process can execute this

--- 306 unchanged lines hidden (view full) ---

1379
1380/*
1381 * get_namelist_local
1382 *
1383 */
1384
1385/*
1386 * Our private version of the switch frontend for getspent. We want
1428 * to search just the nisplus or ldap sp file, so we want to bypass
1387 * to search just the ldap sp file, so we want to bypass
1429 * normal nsswitch.conf based processing. This implementation
1430 * compatible with version 2 of the name service switch.
1431 */
1388 * normal nsswitch.conf based processing. This implementation
1389 * compatible with version 2 of the name service switch.
1390 */
1432#define NSS_NISPLUS_ONLY "nisplus"
1433#define NSS_LDAP_ONLY "ldap"
1434
1435extern int str2spwd(const char *, int, void *, char *, int);
1436
1437static DEFINE_NSS_DB_ROOT(db_root);
1438static DEFINE_NSS_GETENT(context);
1439
1440static char *local_config;
1441static void
1442_lc_nss_initf_shadow(nss_db_params_t *p)
1443{
1444 p->name = NSS_DBNAM_SHADOW;
1445 p->config_name = NSS_DBNAM_PASSWD; /* Use config for "passwd" */
1391#define NSS_LDAP_ONLY "ldap"
1392
1393extern int str2spwd(const char *, int, void *, char *, int);
1394
1395static DEFINE_NSS_DB_ROOT(db_root);
1396static DEFINE_NSS_GETENT(context);
1397
1398static char *local_config;
1399static void
1400_lc_nss_initf_shadow(nss_db_params_t *p)
1401{
1402 p->name = NSS_DBNAM_SHADOW;
1403 p->config_name = NSS_DBNAM_PASSWD; /* Use config for "passwd" */
1446 p->default_config = local_config; /* Use ldap or nisplus only */
1404 p->default_config = local_config; /* Use ldap only */
1447 p->flags = NSS_USE_DEFAULT_CONFIG;
1448}
1449
1450static void
1451_lc_setspent(void)
1452{
1453 nss_setent(&db_root, _lc_nss_initf_shadow, &context);
1454}

--- 74 unchanged lines hidden (view full) ---

1529}
1530
1531int
1532get_namelist(pwu_repository_t repository, char ***namelist, int *num_user)
1533{
1534 if (IS_LDAP(repository)) {
1535 local_config = NSS_LDAP_ONLY;
1536 return (get_namelist_local(namelist, num_user));
1405 p->flags = NSS_USE_DEFAULT_CONFIG;
1406}
1407
1408static void
1409_lc_setspent(void)
1410{
1411 nss_setent(&db_root, _lc_nss_initf_shadow, &context);
1412}

--- 74 unchanged lines hidden (view full) ---

1487}
1488
1489int
1490get_namelist(pwu_repository_t repository, char ***namelist, int *num_user)
1491{
1492 if (IS_LDAP(repository)) {
1493 local_config = NSS_LDAP_ONLY;
1494 return (get_namelist_local(namelist, num_user));
1537 } else if (IS_NISPLUS(repository)) {
1538 local_config = NSS_NISPLUS_ONLY;
1539 return (get_namelist_local(namelist, num_user));
1540 } else if (IS_FILES(repository))
1541 return (get_namelist_files(namelist, num_user));
1542
1543 rusage();
1544 return (BADSYN);
1545}
1546
1547/*

--- 251 unchanged lines hidden (view full) ---

1799
1800void
1801rusage(void)
1802{
1803
1804#define MSG(a) (void) fprintf(stderr, gettext((a)));
1805
1806 MSG("usage:\n");
1495 } else if (IS_FILES(repository))
1496 return (get_namelist_files(namelist, num_user));
1497
1498 rusage();
1499 return (BADSYN);
1500}
1501
1502/*

--- 251 unchanged lines hidden (view full) ---

1754
1755void
1756rusage(void)
1757{
1758
1759#define MSG(a) (void) fprintf(stderr, gettext((a)));
1760
1761 MSG("usage:\n");
1807 MSG("\tpasswd [-r files | -r nis | -r nisplus | -r ldap] [name]\n");
1762 MSG("\tpasswd [-r files | -r nis | -r ldap] [name]\n");
1808 MSG("\tpasswd [-r files] [-egh] [name]\n");
1809 MSG("\tpasswd [-r files] -sa\n");
1810 MSG("\tpasswd [-r files] -s [name]\n");
1811 MSG("\tpasswd [-r files] [-d|-l|-N|-u] [-f] [-n min] [-w warn] "
1812 "[-x max] name\n");
1813 MSG("\tpasswd -r nis [-eg] [name]\n");
1763 MSG("\tpasswd [-r files] [-egh] [name]\n");
1764 MSG("\tpasswd [-r files] -sa\n");
1765 MSG("\tpasswd [-r files] -s [name]\n");
1766 MSG("\tpasswd [-r files] [-d|-l|-N|-u] [-f] [-n min] [-w warn] "
1767 "[-x max] name\n");
1768 MSG("\tpasswd -r nis [-eg] [name]\n");
1814 MSG("\tpasswd -r nisplus [-egh] [-D domainname] [name]\n");
1815 MSG("\tpasswd -r nisplus -sa\n");
1816 MSG("\tpasswd -r nisplus [-D domainname] -s [name]\n");
1817 MSG("\tpasswd -r nisplus [-D domainname] [-l|-N|-u] [-f] [-n min] "
1818 "[-w warn]\n");
1819 MSG("\t\t[-x max] name\n");
1820 MSG("\tpasswd -r ldap [-egh] [name]\n");
1821 MSG("\tpasswd -r ldap -sa\n");
1822 MSG("\tpasswd -r ldap -s [name]\n");
1823 MSG("\tpasswd -r ldap [-l|-N|-u] [-f] [-n min] [-w warn] "
1824 "[-x max] name\n");
1825#undef MSG
1826}
1769 MSG("\t\t[-x max] name\n");
1770 MSG("\tpasswd -r ldap [-egh] [name]\n");
1771 MSG("\tpasswd -r ldap -sa\n");
1772 MSG("\tpasswd -r ldap -s [name]\n");
1773 MSG("\tpasswd -r ldap [-l|-N|-u] [-f] [-n min] [-w warn] "
1774 "[-x max] name\n");
1775#undef MSG
1776}