s4-kdc: Fix logging with the KDB driver
[samba.git] / source4 / kdc / kpasswd_glue.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    kpasswd Server implementation
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
7    Copyright (C) Andrew Tridgell        2005
8
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 3 of the License, or
12    (at your option) any later version.
13
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.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "dsdb/samdb/samdb.h"
25 #include "../lib/util/util_ldb.h"
26 #include "libcli/security/security.h"
27 #include "dsdb/common/util.h"
28 #include "auth/auth.h"
29 #include "kdc/kpasswd_glue.h"
30
31 /*
32    A user password change
33
34    Return true if there is a valid error packet (or success) formed in
35    the error_blob
36 */
37 NTSTATUS samdb_kpasswd_change_password(TALLOC_CTX *mem_ctx,
38                                        struct loadparm_context *lp_ctx,
39                                        struct tevent_context *event_ctx,
40                                        struct ldb_context *samdb,
41                                        struct auth_session_info *session_info,
42                                        const DATA_BLOB *password,
43                                        enum samPwdChangeReason *reject_reason,
44                                        struct samr_DomInfo1 **dominfo,
45                                        const char **error_string,
46                                        NTSTATUS *result)
47 {
48         struct samr_Password *oldLmHash, *oldNtHash;
49         const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL };
50         struct ldb_message *msg;
51         NTSTATUS status;
52         int ret;
53
54         /* Fetch the old hashes to get the old password in order to perform
55          * the password change operation. Naturally it would be much better to
56          * have a password hash from an authentication around but this doesn't
57          * seem to be the case here. */
58         ret = dsdb_search_one(samdb, mem_ctx, &msg, ldb_get_default_basedn(samdb),
59                               LDB_SCOPE_SUBTREE,
60                               attrs,
61                               DSDB_SEARCH_NO_GLOBAL_CATALOG,
62                               "(&(objectClass=user)(sAMAccountName=%s))",
63                               session_info->info->account_name);
64         if (ret != LDB_SUCCESS) {
65                 *error_string = "No such user when changing password";
66                 return NT_STATUS_NO_SUCH_USER;
67         }
68
69         /*
70          * No need to check for password lockout here, the KDC will
71          * have done that when issuing the ticket, which is not based
72          * on the user's password
73          */
74         status = samdb_result_passwords_no_lockout(mem_ctx, lp_ctx, msg,
75                                                    &oldLmHash, &oldNtHash);
76         if (!NT_STATUS_IS_OK(status)) {
77                 *error_string = "Not permitted to change password";
78                 return NT_STATUS_ACCESS_DENIED;
79         }
80
81         /* Start a SAM with user privileges for the password change */
82         samdb = samdb_connect(mem_ctx, event_ctx, lp_ctx,
83                               session_info, 0);
84         if (!samdb) {
85                 *error_string = "Failed to open samdb";
86                 return NT_STATUS_ACCESS_DENIED;
87         }
88
89         DEBUG(3, ("Changing password of %s\\%s (%s)\n",
90                   session_info->info->domain_name,
91                   session_info->info->account_name,
92                   dom_sid_string(mem_ctx, &session_info->security_token->sids[PRIMARY_USER_SID_INDEX])));
93
94         /* Performs the password change */
95         status = samdb_set_password_sid(samdb,
96                                         mem_ctx,
97                                         &session_info->security_token->sids[PRIMARY_USER_SID_INDEX],
98                                         NULL,
99                                         password,
100                                         NULL,
101                                         NULL,
102                                         oldLmHash,
103                                         oldNtHash, /* this is a user password change */
104                                         reject_reason,
105                                         dominfo);
106         if (!NT_STATUS_IS_OK(status)) {
107                 *error_string = nt_errstr(status);
108         }
109         *result = status;
110
111         return NT_STATUS_OK;
112 }