preparing for release of 2.2.3a
[Samba.git] / source / nsswitch / winbindd_pam.c
blob2b6a79694d29d3566736801aa55f246adb250b4b
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
5 Winbind daemon - pam auuth funcions
7 Copyright (C) Andrew Tridgell 2000
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "winbindd.h"
26 /* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
27 form DOMAIN\user into a domain and a user */
29 static BOOL wb_parse_domain_user(char *domuser, fstring domain, fstring user)
31 char *p;
32 char *sep = lp_winbind_separator();
34 p = strchr(domuser,*sep);
36 if (!p)
37 return False;
39 fstrcpy(user, p+1);
40 fstrcpy(domain, domuser);
41 domain[PTR_DIFF(p, domuser)] = 0;
42 strupper(domain);
43 return True;
46 /* Return a password structure from a username. Specify whether cached data
47 can be returned. */
49 enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
51 BOOL result, user_exists;
52 fstring name_domain, name_user;
53 int passlen;
55 DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
56 state->request.data.auth.user));
58 /* Parse domain and username */
60 if (!wb_parse_domain_user(state->request.data.auth.user, name_domain,
61 name_user))
62 return WINBINDD_ERROR;
64 passlen = strlen(state->request.data.auth.pass);
66 /* So domain_client_validate() actually opens a new connection
67 for each authentication performed. This can theoretically
68 be optimised to use an already open IPC$ connection. */
70 result = domain_client_validate(name_user, name_domain,
71 state->request.data.auth.pass,
72 passlen,
73 state->request.data.auth.pass,
74 passlen, &user_exists, NULL);
76 return result ? WINBINDD_OK : WINBINDD_ERROR;
79 /* Challenge Response Authentication Protocol */
81 #if ALLOW_WINBIND_AUTH_CRAP
82 enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
84 NTSTATUS result;
85 fstring name_domain, name_user;
86 unsigned char trust_passwd[16];
87 time_t last_change_time;
88 uint32 smb_uid_low;
89 NET_USER_INFO_3 info3;
90 NET_ID_INFO_CTR ctr;
91 struct cli_state *cli;
93 DEBUG(3, ("[%5d]: pam auth crap %s\n", state->pid,
94 state->request.data.auth_crap.user));
96 /* Parse domain and username */
98 if (!wb_parse_domain_user(state->request.data.auth_crap.user, name_domain,
99 name_user))
100 return WINBINDD_ERROR;
103 * Get the machine account password for our primary domain
106 if (!secrets_fetch_trust_account_password(
107 lp_workgroup(), trust_passwd, &last_change_time)) {
108 DEBUG(0, ("winbindd_pam_auth_crap: could not fetch trust account "
109 "password for domain %s\n", lp_workgroup()));
110 return WINBINDD_ERROR;
113 /* We really don't care what LUID we give the user. */
115 generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
117 ZERO_STRUCT(info3);
119 result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
121 if (!NT_STATUS_IS_OK(result)) {
122 DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
123 goto done;
126 result = cli_nt_login_network(cli, name_domain, name_user, smb_uid_low,
127 state->request.data.auth_crap.chal,
128 state->request.data.auth_crap.lm_resp,
129 state->request.data.auth_crap.nt_resp,
130 &ctr, &info3);
132 cli_shutdown(cli);
134 done:
135 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
137 #endif
139 /* Change a user password */
141 enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
143 char *oldpass, *newpass;
144 fstring domain, user;
145 uchar nt_oldhash[16];
146 uchar lm_oldhash[16];
148 DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid,
149 state->request.data.chauthtok.user));
151 /* Setup crap */
153 if (state == NULL)
154 return WINBINDD_ERROR;
156 if (!wb_parse_domain_user(state->request.data.chauthtok.user, domain, user))
157 return WINBINDD_ERROR;
159 oldpass = state->request.data.chauthtok.oldpass;
160 newpass = state->request.data.chauthtok.newpass;
162 nt_lm_owf_gen(oldpass, nt_oldhash, lm_oldhash);
164 /* Change password */
166 #if 0
168 /* XXX */
170 if (!msrpc_sam_ntchange_pwd(server_state.controller, domain, user,
171 lm_oldhash, nt_oldhash, newpass)) {
172 DEBUG(0, ("password change failed for user %s/%s\n", domain, user));
173 return WINBINDD_ERROR;
175 #endif
177 return WINBINDD_OK;