1/*
2   Unix SMB/CIFS implementation.
3   Password and authentication handling
4   Copyright (C) Andrew Bartlett              2001
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "includes.h"
22
23#undef DBGC_CLASS
24#define DBGC_CLASS DBGC_AUTH
25
26/**
27 * update the encrypted smbpasswd file from the plaintext username and password
28 *
29 *  this ugly hack needs to die, but not quite yet, I think people still use it...
30 **/
31static BOOL update_smbpassword_file(const char *user, const char *password)
32{
33	SAM_ACCOUNT 	*sampass = NULL;
34	BOOL            ret;
35
36	pdb_init_sam(&sampass);
37
38	become_root();
39	ret = pdb_getsampwnam(sampass, user);
40	unbecome_root();
41
42	if(ret == False) {
43		DEBUG(0,("pdb_getsampwnam returned NULL\n"));
44		pdb_free_sam(&sampass);
45		return False;
46	}
47
48	/*
49	 * Remove the account disabled flag - we are updating the
50	 * users password from a login.
51	 */
52	if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED, PDB_CHANGED)) {
53		pdb_free_sam(&sampass);
54		return False;
55	}
56
57	if (!pdb_set_plaintext_passwd (sampass, password)) {
58		pdb_free_sam(&sampass);
59		return False;
60	}
61
62	/* Now write it into the file. */
63	become_root();
64
65	ret = pdb_update_sam_account (sampass);
66
67	unbecome_root();
68
69	if (ret) {
70		DEBUG(3,("pdb_update_sam_account returned %d\n",ret));
71	}
72
73	pdb_free_sam(&sampass);
74	return ret;
75}
76
77
78/** Check a plaintext username/password
79 *
80 * Cannot deal with an encrupted password in any manner whatsoever,
81 * unless the account has a null password.
82 **/
83
84static NTSTATUS check_unix_security(const struct auth_context *auth_context,
85			     void *my_private_data,
86			     TALLOC_CTX *mem_ctx,
87			     const auth_usersupplied_info *user_info,
88			     auth_serversupplied_info **server_info)
89{
90	NTSTATUS nt_status;
91	struct passwd *pass = NULL;
92
93	become_root();
94	pass = Get_Pwnam(user_info->internal_username.str);
95
96
97	/** @todo This call assumes a ASCII password, no charset transformation is
98	    done.  We may need to revisit this **/
99	nt_status = pass_check(pass,
100				pass ? pass->pw_name : user_info->internal_username.str,
101				(char *)user_info->plaintext_password.data,
102				user_info->plaintext_password.length-1,
103				lp_update_encrypted() ?
104				update_smbpassword_file : NULL,
105				True);
106
107	unbecome_root();
108
109	if (NT_STATUS_IS_OK(nt_status)) {
110		if (pass) {
111			make_server_info_pw(server_info, pass->pw_name, pass);
112		} else {
113			/* we need to do somthing more useful here */
114			nt_status = NT_STATUS_NO_SUCH_USER;
115		}
116	}
117
118	return nt_status;
119}
120
121/* module initialisation */
122static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method)
123{
124	if (!make_auth_methods(auth_context, auth_method)) {
125		return NT_STATUS_NO_MEMORY;
126	}
127
128	(*auth_method)->name = "unix";
129	(*auth_method)->auth = check_unix_security;
130	return NT_STATUS_OK;
131}
132
133NTSTATUS auth_unix_init(void)
134{
135	return smb_register_auth(AUTH_INTERFACE_VERSION, "unix", auth_init_unix);
136}
137