pam_passwd.c revision 1.1 1 /*-
2 * Copyright (c) 2002 Networks Associates Technologies, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * NAI Labs, the Security Research Division of Network Associates, Inc.
7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
8 * DARPA CHATS research program.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #ifdef __FreeBSD__
37 __FBSDID("$FreeBSD: src/usr.bin/passwd/passwd.c,v 1.23 2003/04/18 21:27:09 nectar Exp $");
38 #else
39 __RCSID("$NetBSD: pam_passwd.c,v 1.1 2005/02/22 01:08:43 christos Exp $");
40 #endif
41
42 #include <sys/param.h>
43
44 #include <err.h>
45 #include <pwd.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <syslog.h>
49 #include <unistd.h>
50
51 #include "extern.h"
52
53 #include <security/pam_appl.h>
54 #include <security/openpam.h>
55
56 static pam_handle_t *pamh;
57 static struct pam_conv pamc = {
58 openpam_ttyconv,
59 NULL
60 };
61
62 static const char *progname;
63 static const char *yp_domain;
64 static const char *yp_server;
65 static int usage = PW_DONT_USE;
66
67 #define pam_check(func) do { \
68 if (pam_err != PAM_SUCCESS) { \
69 if (pam_err == PAM_AUTH_ERR || pam_err == PAM_PERM_DENIED || \
70 pam_err == PAM_AUTHTOK_RECOVERY_ERR) \
71 warnx("sorry"); \
72 else \
73 warnx("%s(): %s", func, pam_strerror(pamh, pam_err)); \
74 goto end; \
75 } \
76 } while (0)
77
78
79 int
80 pwpam_init(const char *pname)
81 {
82 progname = pname;
83 return 0;
84 }
85
86 int
87 pwpam_arg(char arg, const char *optarg)
88 {
89 switch (arg) {
90 case 'p':
91 usage = PW_USE_FORCE;
92 break;
93 case 'd':
94 yp_domain = optarg;
95 break;
96 case 's':
97 yp_server = optarg;
98 break;
99 default:
100 return 0;
101 }
102 return 1;
103 }
104
105 int
106 pwpam_arg_end(void)
107 {
108 return usage;
109 }
110
111 void
112 pwpam_end(void)
113 {
114 /* NOOP */
115 }
116
117 int
118 pwpam_chpw(const char *uname)
119 {
120 int pam_err;
121 char hostname[MAXHOSTNAMELEN + 1];
122
123 /* initialize PAM */
124 pam_err = pam_start(progname, uname, &pamc, &pamh);
125 pam_check("pam_start");
126
127 pam_err = pam_set_item(pamh, PAM_TTY, ttyname(STDERR_FILENO));
128 pam_check("pam_set_item");
129 (void)gethostname(hostname, sizeof hostname);
130 pam_err = pam_set_item(pamh, PAM_RHOST, hostname);
131 pam_check("pam_set_item");
132 pam_err = pam_set_item(pamh, PAM_RUSER, getlogin());
133 pam_check("pam_set_item");
134
135 /* set YP domain and host */
136 pam_err = pam_set_data(pamh, "yp_domain", __UNCONST(yp_domain), NULL);
137 pam_check("pam_set_data");
138 pam_err = pam_set_data(pamh, "yp_server", __UNCONST(yp_server), NULL);
139 pam_check("pam_set_data");
140
141 /* set new password */
142 pam_err = pam_chauthtok(pamh, 0);
143 pam_check("pam_chauthtok");
144
145 end:
146 pam_end(pamh, pam_err);
147 return pam_err == PAM_SUCCESS ? 0 : 1;
148 }
149