2 Unix SMB/CIFS implementation.
3 SAMR Pipe utility functions.
5 Copyright (C) Luke Kenneth Casson Leighton 1996-1998
6 Copyright (C) Gerald (Jerry) Carter 2000-2001
7 Copyright (C) Andrew Bartlett 2001-2002
8 Copyright (C) Stefan (metze) Metzmacher 2002
9 Copyright (C) Guenther Deschner 2008
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #define DBGC_CLASS DBGC_RPC_SRV
30 #define STRING_CHANGED (old_string && !new_string) ||\
31 (!old_string && new_string) ||\
32 (old_string && new_string && (strcmp(old_string, new_string) != 0))
34 #define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\
36 ((s1) && (s2) && (strcmp((s1), (s2)) != 0))
38 /*************************************************************
39 Copies a struct samr_UserInfo20 to a struct samu
40 **************************************************************/
42 void copy_id20_to_sam_passwd(struct samu *to,
43 struct samr_UserInfo20 *from)
45 const char *old_string;
49 if (from == NULL || to == NULL) {
53 if (from->parameters.string) {
54 old_string = pdb_get_munged_dial(to);
55 mung.length = from->parameters.length;
56 mung.data = (uint8_t *)from->parameters.string;
58 new_string = (mung.length == 0) ?
59 NULL : base64_encode_data_blob(talloc_tos(), mung);
60 DEBUG(10,("INFO_20 PARAMETERS: %s -> %s\n",
61 old_string, new_string));
62 if (STRING_CHANGED_NC(old_string,new_string)) {
63 pdb_set_munged_dial(to, new_string, PDB_CHANGED);
66 TALLOC_FREE(new_string);
70 /*************************************************************
71 Copies a struct samr_UserInfo21 to a struct samu
72 **************************************************************/
74 void copy_id21_to_sam_passwd(const char *log_prefix,
76 struct samr_UserInfo21 *from)
78 time_t unix_time, stored_time;
79 const char *old_string, *new_string;
83 if (from == NULL || to == NULL) {
93 if (from->fields_present & SAMR_FIELD_LAST_LOGON) {
94 unix_time = nt_time_to_unix(from->last_logon);
95 stored_time = pdb_get_logon_time(to);
96 DEBUG(10,("%s SAMR_FIELD_LAST_LOGON: %lu -> %lu\n", l,
97 (long unsigned int)stored_time,
98 (long unsigned int)unix_time));
99 if (stored_time != unix_time) {
100 pdb_set_logon_time(to, unix_time, PDB_CHANGED);
104 if (from->fields_present & SAMR_FIELD_LAST_LOGOFF) {
105 unix_time = nt_time_to_unix(from->last_logoff);
106 stored_time = pdb_get_logoff_time(to);
107 DEBUG(10,("%s SAMR_FIELD_LAST_LOGOFF: %lu -> %lu\n", l,
108 (long unsigned int)stored_time,
109 (long unsigned int)unix_time));
110 if (stored_time != unix_time) {
111 pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
115 if (from->fields_present & SAMR_FIELD_ACCT_EXPIRY) {
116 unix_time = nt_time_to_unix(from->acct_expiry);
117 stored_time = pdb_get_kickoff_time(to);
118 DEBUG(10,("%s SAMR_FIELD_ACCT_EXPIRY: %lu -> %lu\n", l,
119 (long unsigned int)stored_time,
120 (long unsigned int)unix_time));
121 if (stored_time != unix_time) {
122 pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
126 if (from->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
127 unix_time = nt_time_to_unix(from->last_password_change);
128 stored_time = pdb_get_pass_last_set_time(to);
129 DEBUG(10,("%s SAMR_FIELD_LAST_PWD_CHANGE: %lu -> %lu\n", l,
130 (long unsigned int)stored_time,
131 (long unsigned int)unix_time));
132 if (stored_time != unix_time) {
133 pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
137 if ((from->fields_present & SAMR_FIELD_ACCOUNT_NAME) &&
138 (from->account_name.string)) {
139 old_string = pdb_get_username(to);
140 new_string = from->account_name.string;
141 DEBUG(10,("%s SAMR_FIELD_ACCOUNT_NAME: %s -> %s\n", l,
142 old_string, new_string));
143 if (STRING_CHANGED) {
144 pdb_set_username(to, new_string, PDB_CHANGED);
148 if ((from->fields_present & SAMR_FIELD_FULL_NAME) &&
149 (from->full_name.string)) {
150 old_string = pdb_get_fullname(to);
151 new_string = from->full_name.string;
152 DEBUG(10,("%s SAMR_FIELD_FULL_NAME: %s -> %s\n", l,
153 old_string, new_string));
154 if (STRING_CHANGED) {
155 pdb_set_fullname(to, new_string, PDB_CHANGED);
159 if ((from->fields_present & SAMR_FIELD_HOME_DIRECTORY) &&
160 (from->home_directory.string)) {
161 old_string = pdb_get_homedir(to);
162 new_string = from->home_directory.string;
163 DEBUG(10,("%s SAMR_FIELD_HOME_DIRECTORY: %s -> %s\n", l,
164 old_string, new_string));
165 if (STRING_CHANGED) {
166 pdb_set_homedir(to, new_string, PDB_CHANGED);
170 if ((from->fields_present & SAMR_FIELD_HOME_DRIVE) &&
171 (from->home_drive.string)) {
172 old_string = pdb_get_dir_drive(to);
173 new_string = from->home_drive.string;
174 DEBUG(10,("%s SAMR_FIELD_HOME_DRIVE: %s -> %s\n", l,
175 old_string, new_string));
176 if (STRING_CHANGED) {
177 pdb_set_dir_drive(to, new_string, PDB_CHANGED);
181 if ((from->fields_present & SAMR_FIELD_LOGON_SCRIPT) &&
182 (from->logon_script.string)) {
183 old_string = pdb_get_logon_script(to);
184 new_string = from->logon_script.string;
185 DEBUG(10,("%s SAMR_FIELD_LOGON_SCRIPT: %s -> %s\n", l,
186 old_string, new_string));
187 if (STRING_CHANGED) {
188 pdb_set_logon_script(to , new_string, PDB_CHANGED);
192 if ((from->fields_present & SAMR_FIELD_PROFILE_PATH) &&
193 (from->profile_path.string)) {
194 old_string = pdb_get_profile_path(to);
195 new_string = from->profile_path.string;
196 DEBUG(10,("%s SAMR_FIELD_PROFILE_PATH: %s -> %s\n", l,
197 old_string, new_string));
198 if (STRING_CHANGED) {
199 pdb_set_profile_path(to , new_string, PDB_CHANGED);
203 if ((from->fields_present & SAMR_FIELD_DESCRIPTION) &&
204 (from->description.string)) {
205 old_string = pdb_get_acct_desc(to);
206 new_string = from->description.string;
207 DEBUG(10,("%s SAMR_FIELD_DESCRIPTION: %s -> %s\n", l,
208 old_string, new_string));
209 if (STRING_CHANGED) {
210 pdb_set_acct_desc(to, new_string, PDB_CHANGED);
214 if ((from->fields_present & SAMR_FIELD_WORKSTATIONS) &&
215 (from->workstations.string)) {
216 old_string = pdb_get_workstations(to);
217 new_string = from->workstations.string;
218 DEBUG(10,("%s SAMR_FIELD_WORKSTATIONS: %s -> %s\n", l,
219 old_string, new_string));
220 if (STRING_CHANGED) {
221 pdb_set_workstations(to , new_string, PDB_CHANGED);
225 if ((from->fields_present & SAMR_FIELD_COMMENT) &&
226 (from->comment.string)) {
227 old_string = pdb_get_comment(to);
228 new_string = from->comment.string;
229 DEBUG(10,("%s SAMR_FIELD_COMMENT: %s -> %s\n", l,
230 old_string, new_string));
231 if (STRING_CHANGED) {
232 pdb_set_comment(to, new_string, PDB_CHANGED);
236 if ((from->fields_present & SAMR_FIELD_PARAMETERS) &&
237 (from->parameters.string)) {
239 old_string = pdb_get_munged_dial(to);
240 mung.length = from->parameters.length;
241 mung.data = (uint8_t *)from->parameters.string;
243 newstr = (mung.length == 0) ?
244 NULL : base64_encode_data_blob(talloc_tos(), mung);
245 DEBUG(10,("%s SAMR_FIELD_PARAMETERS: %s -> %s\n", l,
246 old_string, newstr));
247 if (STRING_CHANGED_NC(old_string,newstr)) {
248 pdb_set_munged_dial(to, newstr, PDB_CHANGED);
254 if (from->fields_present & SAMR_FIELD_RID) {
255 if (from->rid == 0) {
256 DEBUG(10,("%s: Asked to set User RID to 0 !? Skipping change!\n", l));
257 } else if (from->rid != pdb_get_user_rid(to)) {
258 DEBUG(10,("%s SAMR_FIELD_RID: %u -> %u NOT UPDATED!\n", l,
259 pdb_get_user_rid(to), from->rid));
263 if (from->fields_present & SAMR_FIELD_PRIMARY_GID) {
264 if (from->primary_gid == 0) {
265 DEBUG(10,("%s: Asked to set Group RID to 0 !? Skipping change!\n", l));
266 } else if (from->primary_gid != pdb_get_group_rid(to)) {
267 DEBUG(10,("%s SAMR_FIELD_PRIMARY_GID: %u -> %u\n", l,
268 pdb_get_group_rid(to), from->primary_gid));
269 pdb_set_group_sid_from_rid(to,
270 from->primary_gid, PDB_CHANGED);
274 if (from->fields_present & SAMR_FIELD_ACCT_FLAGS) {
275 DEBUG(10,("%s SAMR_FIELD_ACCT_FLAGS: %08X -> %08X\n", l,
276 pdb_get_acct_ctrl(to), from->acct_flags));
277 if (from->acct_flags != pdb_get_acct_ctrl(to)) {
278 if (!(from->acct_flags & ACB_AUTOLOCK) &&
279 (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
280 /* We're unlocking a previously locked user. Reset bad password counts.
281 Patch from Jianliang Lu. <Jianliang.Lu@getronics.com> */
282 pdb_set_bad_password_count(to, 0, PDB_CHANGED);
283 pdb_set_bad_password_time(to, 0, PDB_CHANGED);
285 pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
289 if (from->fields_present & SAMR_FIELD_LOGON_HOURS) {
290 char oldstr[44]; /* hours strings are 42 bytes. */
292 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l,
293 pdb_get_logon_divs(to), from->logon_hours.units_per_week));
294 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) {
295 pdb_set_logon_divs(to,
296 from->logon_hours.units_per_week, PDB_CHANGED);
299 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l,
300 pdb_get_hours_len(to),
301 from->logon_hours.units_per_week/8));
302 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) {
303 pdb_set_hours_len(to,
304 from->logon_hours.units_per_week/8, PDB_CHANGED);
307 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l,
308 pdb_get_hours(to), from->logon_hours.bits));
309 pdb_sethexhours(oldstr, pdb_get_hours(to));
310 pdb_sethexhours(newstr, from->logon_hours.bits);
311 if (!strequal(oldstr, newstr)) {
312 pdb_set_hours(to, from->logon_hours.bits, PDB_CHANGED);
316 if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) {
317 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l,
318 pdb_get_bad_password_count(to), from->bad_password_count));
319 if (from->bad_password_count != pdb_get_bad_password_count(to)) {
320 pdb_set_bad_password_count(to,
321 from->bad_password_count, PDB_CHANGED);
325 if (from->fields_present & SAMR_FIELD_NUM_LOGONS) {
326 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l,
327 pdb_get_logon_count(to), from->logon_count));
328 if (from->logon_count != pdb_get_logon_count(to)) {
329 pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
333 /* If the must change flag is set, the last set time goes to zero.
334 the must change and can change fields also do, but they are
335 calculated from policy, not set from the wire */
337 if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
338 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
339 from->password_expired));
340 if (from->password_expired == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
341 pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
343 pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
349 /*************************************************************
350 Copies a struct samr_UserInfo23 to a struct samu
351 **************************************************************/
353 void copy_id23_to_sam_passwd(struct samu *to,
354 struct samr_UserInfo23 *from)
356 if (from == NULL || to == NULL) {
360 copy_id21_to_sam_passwd("INFO 23", to, &from->info);
363 /*************************************************************
364 Copies a struct samr_UserInfo25 to a struct samu
365 **************************************************************/
367 void copy_id25_to_sam_passwd(struct samu *to,
368 struct samr_UserInfo25 *from)
370 if (from == NULL || to == NULL) {
374 copy_id21_to_sam_passwd("INFO_25", to, &from->info);