Fix very old bug in ASQ
[Samba/ekacnet.git] / source3 / rpc_server / srv_samr_util.c
blobef588aed1a38c8220a3a834995f22bc579bec919
1 /*
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/>.
25 #include "includes.h"
27 #undef DBGC_CLASS
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)) ||\
35 (!(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;
46 char *new_string;
47 DATA_BLOB mung;
49 if (from == NULL || to == NULL) {
50 return;
53 if (from->parameters.array) {
54 old_string = pdb_get_munged_dial(to);
55 mung = data_blob_const(from->parameters.array,
56 from->parameters.length);
57 new_string = (mung.length == 0) ?
58 NULL : base64_encode_data_blob(talloc_tos(), mung);
59 DEBUG(10,("INFO_20 PARAMETERS: %s -> %s\n",
60 old_string, new_string));
61 if (STRING_CHANGED_NC(old_string,new_string)) {
62 pdb_set_munged_dial(to, new_string, PDB_CHANGED);
65 TALLOC_FREE(new_string);
69 /*************************************************************
70 Copies a struct samr_UserInfo21 to a struct samu
71 **************************************************************/
73 void copy_id21_to_sam_passwd(const char *log_prefix,
74 struct samu *to,
75 struct samr_UserInfo21 *from)
77 time_t unix_time, stored_time;
78 const char *old_string, *new_string;
79 const char *l;
81 if (from == NULL || to == NULL) {
82 return;
85 if (log_prefix) {
86 l = log_prefix;
87 } else {
88 l = "INFO_21";
91 if (from->fields_present & SAMR_FIELD_LAST_LOGON) {
92 unix_time = nt_time_to_unix(from->last_logon);
93 stored_time = pdb_get_logon_time(to);
94 DEBUG(10,("%s SAMR_FIELD_LAST_LOGON: %lu -> %lu\n", l,
95 (long unsigned int)stored_time,
96 (long unsigned int)unix_time));
97 if (stored_time != unix_time) {
98 pdb_set_logon_time(to, unix_time, PDB_CHANGED);
102 if (from->fields_present & SAMR_FIELD_LAST_LOGOFF) {
103 unix_time = nt_time_to_unix(from->last_logoff);
104 stored_time = pdb_get_logoff_time(to);
105 DEBUG(10,("%s SAMR_FIELD_LAST_LOGOFF: %lu -> %lu\n", l,
106 (long unsigned int)stored_time,
107 (long unsigned int)unix_time));
108 if (stored_time != unix_time) {
109 pdb_set_logoff_time(to, unix_time, PDB_CHANGED);
113 if (from->fields_present & SAMR_FIELD_ACCT_EXPIRY) {
114 unix_time = nt_time_to_unix(from->acct_expiry);
115 stored_time = pdb_get_kickoff_time(to);
116 DEBUG(10,("%s SAMR_FIELD_ACCT_EXPIRY: %lu -> %lu\n", l,
117 (long unsigned int)stored_time,
118 (long unsigned int)unix_time));
119 if (stored_time != unix_time) {
120 pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
124 if (from->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
125 unix_time = nt_time_to_unix(from->last_password_change);
126 stored_time = pdb_get_pass_last_set_time(to);
127 DEBUG(10,("%s SAMR_FIELD_LAST_PWD_CHANGE: %lu -> %lu\n", l,
128 (long unsigned int)stored_time,
129 (long unsigned int)unix_time));
130 if (stored_time != unix_time) {
131 pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
135 if ((from->fields_present & SAMR_FIELD_ACCOUNT_NAME) &&
136 (from->account_name.string)) {
137 old_string = pdb_get_username(to);
138 new_string = from->account_name.string;
139 DEBUG(10,("%s SAMR_FIELD_ACCOUNT_NAME: %s -> %s\n", l,
140 old_string, new_string));
141 if (STRING_CHANGED) {
142 pdb_set_username(to, new_string, PDB_CHANGED);
146 if ((from->fields_present & SAMR_FIELD_FULL_NAME) &&
147 (from->full_name.string)) {
148 old_string = pdb_get_fullname(to);
149 new_string = from->full_name.string;
150 DEBUG(10,("%s SAMR_FIELD_FULL_NAME: %s -> %s\n", l,
151 old_string, new_string));
152 if (STRING_CHANGED) {
153 pdb_set_fullname(to, new_string, PDB_CHANGED);
157 if ((from->fields_present & SAMR_FIELD_HOME_DIRECTORY) &&
158 (from->home_directory.string)) {
159 old_string = pdb_get_homedir(to);
160 new_string = from->home_directory.string;
161 DEBUG(10,("%s SAMR_FIELD_HOME_DIRECTORY: %s -> %s\n", l,
162 old_string, new_string));
163 if (STRING_CHANGED) {
164 pdb_set_homedir(to, new_string, PDB_CHANGED);
168 if ((from->fields_present & SAMR_FIELD_HOME_DRIVE) &&
169 (from->home_drive.string)) {
170 old_string = pdb_get_dir_drive(to);
171 new_string = from->home_drive.string;
172 DEBUG(10,("%s SAMR_FIELD_HOME_DRIVE: %s -> %s\n", l,
173 old_string, new_string));
174 if (STRING_CHANGED) {
175 pdb_set_dir_drive(to, new_string, PDB_CHANGED);
179 if ((from->fields_present & SAMR_FIELD_LOGON_SCRIPT) &&
180 (from->logon_script.string)) {
181 old_string = pdb_get_logon_script(to);
182 new_string = from->logon_script.string;
183 DEBUG(10,("%s SAMR_FIELD_LOGON_SCRIPT: %s -> %s\n", l,
184 old_string, new_string));
185 if (STRING_CHANGED) {
186 pdb_set_logon_script(to , new_string, PDB_CHANGED);
190 if ((from->fields_present & SAMR_FIELD_PROFILE_PATH) &&
191 (from->profile_path.string)) {
192 old_string = pdb_get_profile_path(to);
193 new_string = from->profile_path.string;
194 DEBUG(10,("%s SAMR_FIELD_PROFILE_PATH: %s -> %s\n", l,
195 old_string, new_string));
196 if (STRING_CHANGED) {
197 pdb_set_profile_path(to , new_string, PDB_CHANGED);
201 if ((from->fields_present & SAMR_FIELD_DESCRIPTION) &&
202 (from->description.string)) {
203 old_string = pdb_get_acct_desc(to);
204 new_string = from->description.string;
205 DEBUG(10,("%s SAMR_FIELD_DESCRIPTION: %s -> %s\n", l,
206 old_string, new_string));
207 if (STRING_CHANGED) {
208 pdb_set_acct_desc(to, new_string, PDB_CHANGED);
212 if ((from->fields_present & SAMR_FIELD_WORKSTATIONS) &&
213 (from->workstations.string)) {
214 old_string = pdb_get_workstations(to);
215 new_string = from->workstations.string;
216 DEBUG(10,("%s SAMR_FIELD_WORKSTATIONS: %s -> %s\n", l,
217 old_string, new_string));
218 if (STRING_CHANGED) {
219 pdb_set_workstations(to , new_string, PDB_CHANGED);
223 if ((from->fields_present & SAMR_FIELD_COMMENT) &&
224 (from->comment.string)) {
225 old_string = pdb_get_comment(to);
226 new_string = from->comment.string;
227 DEBUG(10,("%s SAMR_FIELD_COMMENT: %s -> %s\n", l,
228 old_string, new_string));
229 if (STRING_CHANGED) {
230 pdb_set_comment(to, new_string, PDB_CHANGED);
234 if ((from->fields_present & SAMR_FIELD_PARAMETERS) &&
235 (from->parameters.array)) {
236 char *newstr;
237 DATA_BLOB mung;
238 old_string = pdb_get_munged_dial(to);
240 mung = data_blob_const(from->parameters.array,
241 from->parameters.length);
242 newstr = (mung.length == 0) ?
243 NULL : base64_encode_data_blob(talloc_tos(), mung);
244 DEBUG(10,("%s SAMR_FIELD_PARAMETERS: %s -> %s\n", l,
245 old_string, newstr));
246 if (STRING_CHANGED_NC(old_string,newstr)) {
247 pdb_set_munged_dial(to, newstr, PDB_CHANGED);
250 TALLOC_FREE(newstr);
253 if (from->fields_present & SAMR_FIELD_RID) {
254 if (from->rid == 0) {
255 DEBUG(10,("%s: Asked to set User RID to 0 !? Skipping change!\n", l));
256 } else if (from->rid != pdb_get_user_rid(to)) {
257 DEBUG(10,("%s SAMR_FIELD_RID: %u -> %u NOT UPDATED!\n", l,
258 pdb_get_user_rid(to), from->rid));
262 if (from->fields_present & SAMR_FIELD_PRIMARY_GID) {
263 if (from->primary_gid == 0) {
264 DEBUG(10,("%s: Asked to set Group RID to 0 !? Skipping change!\n", l));
265 } else if (from->primary_gid != pdb_get_group_rid(to)) {
266 DEBUG(10,("%s SAMR_FIELD_PRIMARY_GID: %u -> %u\n", l,
267 pdb_get_group_rid(to), from->primary_gid));
268 pdb_set_group_sid_from_rid(to,
269 from->primary_gid, PDB_CHANGED);
273 if (from->fields_present & SAMR_FIELD_ACCT_FLAGS) {
274 DEBUG(10,("%s SAMR_FIELD_ACCT_FLAGS: %08X -> %08X\n", l,
275 pdb_get_acct_ctrl(to), from->acct_flags));
276 if (from->acct_flags != pdb_get_acct_ctrl(to)) {
277 if (!(from->acct_flags & ACB_AUTOLOCK) &&
278 (pdb_get_acct_ctrl(to) & ACB_AUTOLOCK)) {
279 /* We're unlocking a previously locked user. Reset bad password counts.
280 Patch from Jianliang Lu. <Jianliang.Lu@getronics.com> */
281 pdb_set_bad_password_count(to, 0, PDB_CHANGED);
282 pdb_set_bad_password_time(to, 0, PDB_CHANGED);
284 pdb_set_acct_ctrl(to, from->acct_flags, PDB_CHANGED);
288 if (from->fields_present & SAMR_FIELD_LOGON_HOURS) {
289 char oldstr[44]; /* hours strings are 42 bytes. */
290 char newstr[44];
291 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week): %08X -> %08X\n", l,
292 pdb_get_logon_divs(to), from->logon_hours.units_per_week));
293 if (from->logon_hours.units_per_week != pdb_get_logon_divs(to)) {
294 pdb_set_logon_divs(to,
295 from->logon_hours.units_per_week, PDB_CHANGED);
298 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (units_per_week/8): %08X -> %08X\n", l,
299 pdb_get_hours_len(to),
300 from->logon_hours.units_per_week/8));
301 if (from->logon_hours.units_per_week/8 != pdb_get_hours_len(to)) {
302 pdb_set_hours_len(to,
303 from->logon_hours.units_per_week/8, PDB_CHANGED);
306 DEBUG(15,("%s SAMR_FIELD_LOGON_HOURS (bits): %s -> %s\n", l,
307 pdb_get_hours(to), from->logon_hours.bits));
308 pdb_sethexhours(oldstr, pdb_get_hours(to));
309 pdb_sethexhours(newstr, from->logon_hours.bits);
310 if (!strequal(oldstr, newstr)) {
311 pdb_set_hours(to, from->logon_hours.bits, PDB_CHANGED);
315 if (from->fields_present & SAMR_FIELD_BAD_PWD_COUNT) {
316 DEBUG(10,("%s SAMR_FIELD_BAD_PWD_COUNT: %08X -> %08X\n", l,
317 pdb_get_bad_password_count(to), from->bad_password_count));
318 if (from->bad_password_count != pdb_get_bad_password_count(to)) {
319 pdb_set_bad_password_count(to,
320 from->bad_password_count, PDB_CHANGED);
324 if (from->fields_present & SAMR_FIELD_NUM_LOGONS) {
325 DEBUG(10,("%s SAMR_FIELD_NUM_LOGONS: %08X -> %08X\n", l,
326 pdb_get_logon_count(to), from->logon_count));
327 if (from->logon_count != pdb_get_logon_count(to)) {
328 pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
332 /* If the must change flag is set, the last set time goes to zero.
333 the must change and can change fields also do, but they are
334 calculated from policy, not set from the wire */
336 if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
337 DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
338 from->password_expired));
339 if (from->password_expired == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
340 pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
341 } else {
342 /* A subtlety here: some windows commands will
343 clear the expired flag even though it's not
344 set, and we don't want to reset the time
345 in these caess. "net user /dom <user> /active:y"
346 for example, to clear an autolocked acct.
347 We must check to see if it's expired first. jmcd */
348 stored_time = pdb_get_pass_last_set_time(to);
349 if (stored_time == 0)
350 pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
356 /*************************************************************
357 Copies a struct samr_UserInfo23 to a struct samu
358 **************************************************************/
360 void copy_id23_to_sam_passwd(struct samu *to,
361 struct samr_UserInfo23 *from)
363 if (from == NULL || to == NULL) {
364 return;
367 copy_id21_to_sam_passwd("INFO 23", to, &from->info);
370 /*************************************************************
371 Copies a struct samr_UserInfo25 to a struct samu
372 **************************************************************/
374 void copy_id25_to_sam_passwd(struct samu *to,
375 struct samr_UserInfo25 *from)
377 if (from == NULL || to == NULL) {
378 return;
381 copy_id21_to_sam_passwd("INFO_25", to, &from->info);