2 Unix SMB/CIFS implementation.
3 krb5 set password implementation
4 Copyright (C) Remus Koos 2001 (remuskoos@yahoo.com)
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 3 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "librpc/gen_ndr/ndr_secrets.h"
26 ADS_STATUS
ads_change_trust_account_password(ADS_STRUCT
*ads
, char *host_principal
)
28 const char *password
= NULL
;
29 const char *new_password
= NULL
;
31 const char *domain
= lp_workgroup();
32 struct secrets_domain_info1
*info
= NULL
;
33 struct secrets_domain_info1_change
*prev
= NULL
;
34 const DATA_BLOB
*cleartext_blob
= NULL
;
35 DATA_BLOB pw_blob
= data_blob_null
;
36 DATA_BLOB new_pw_blob
= data_blob_null
;
38 struct timeval tv
= timeval_current();
39 NTTIME now
= timeval_to_nttime(&tv
);
40 int role
= lp_server_role();
43 if (role
!= ROLE_DOMAIN_MEMBER
) {
44 DBG_ERR("Machine account password change only supported on a DOMAIN_MEMBER.\n");
45 return ADS_ERROR_NT(NT_STATUS_INVALID_SERVER_STATE
);
48 new_password
= trust_pw_new_value(talloc_tos(), SEC_CHAN_WKSTA
, SEC_ADS
);
49 if (new_password
== NULL
) {
50 ret
= ADS_ERROR_SYSTEM(errno
);
51 DEBUG(1,("Failed to generate machine password\n"));
55 status
= secrets_prepare_password_change(domain
,
60 if (!NT_STATUS_IS_OK(status
)) {
61 return ADS_ERROR_NT(status
);
64 status
= NT_STATUS_REQUEST_NOT_ACCEPTED
;
65 secrets_failed_password_change("localhost",
67 NT_STATUS_NOT_COMMITTED
,
69 return ADS_ERROR_NT(status
);
72 cleartext_blob
= &info
->password
->cleartext_blob
;
73 ok
= convert_string_talloc(talloc_tos(), CH_UTF16MUNGED
, CH_UNIX
,
75 cleartext_blob
->length
,
76 (void **)&pw_blob
.data
,
79 status
= NT_STATUS_UNMAPPABLE_CHARACTER
;
80 if (errno
== ENOMEM
) {
81 status
= NT_STATUS_NO_MEMORY
;
83 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
84 "failed for password of %s - %s\n",
85 domain
, nt_errstr(status
));
86 return ADS_ERROR_NT(status
);
88 password
= (const char *)pw_blob
.data
;
90 cleartext_blob
= &info
->next_change
->password
->cleartext_blob
;
91 ok
= convert_string_talloc(talloc_tos(), CH_UTF16MUNGED
, CH_UNIX
,
93 cleartext_blob
->length
,
94 (void **)&new_pw_blob
.data
,
97 status
= NT_STATUS_UNMAPPABLE_CHARACTER
;
98 if (errno
== ENOMEM
) {
99 status
= NT_STATUS_NO_MEMORY
;
101 DBG_ERR("convert_string_talloc(CH_UTF16MUNGED, CH_UNIX) "
102 "failed for new_password of %s - %s\n",
103 domain
, nt_errstr(status
));
104 secrets_failed_password_change("localhost",
106 NT_STATUS_NOT_COMMITTED
,
108 return ADS_ERROR_NT(status
);
110 new_password
= (const char *)new_pw_blob
.data
;
112 ret
= kerberos_set_password(ads
->auth
.kdc_server
, host_principal
, password
, host_principal
, new_password
, ads
->auth
.time_offset
);
114 if (!ADS_ERR_OK(ret
)) {
115 status
= ads_ntstatus(ret
);
116 DBG_ERR("kerberos_set_password(%s, %s) "
117 "failed for new_password of %s - %s\n",
118 ads
->auth
.kdc_server
, host_principal
,
119 domain
, nt_errstr(status
));
120 secrets_failed_password_change(ads
->auth
.kdc_server
,
121 NT_STATUS_NOT_COMMITTED
,
127 status
= secrets_finish_password_change(ads
->auth
.kdc_server
, now
, info
);
128 if (!NT_STATUS_IS_OK(status
)) {
129 DEBUG(1,("Failed to save machine password\n"));
130 return ADS_ERROR_NT(status
);