r9755: Fix crash bug in SWAT login
[sfrench/samba-autobuild/.git] / source4 / lib / samba3 / upgrade.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Generate ldb_message 's for samba3_*
4
5     Copyright (C) Jelmer Vernooij       2005
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23 #include "lib/samba3/samba3.h"
24 #include "lib/ldb/include/ldb.h"
25
26 static struct ldb_message *msg_array_add(struct ldb_context *ctx, struct ldb_message ***msgs, int *count)
27 {
28         struct ldb_message *ret;
29         *msgs = talloc_realloc(ctx, *msgs, struct ldb_message *, (*count)+1);
30
31         ret = (*msgs)[*count] = talloc_zero(ctx, struct ldb_message);
32         (*count)++;
33
34         return ret;
35 }
36
37 static struct ldb_dn *regkey_to_dn(struct ldb_context *ldb, const char *name)
38 {
39         char *p, *n, *dup;
40         struct ldb_dn *ret = ldb_dn_explode(ldb, "hive=NONE");
41
42         p = dup = talloc_strdup(ldb, name);
43
44         while (p) {
45                 n = strchr(p, '/');
46                 if (n) { *n = '\0';     n++; }
47
48                 ret = ldb_dn_build_child(ldb, "key", p, ret);
49
50                 p = n;
51         }
52
53         talloc_free(dup);
54
55         return ret;
56 }
57
58 /* Where prefix is any of:
59  * - HKLM
60  *   HKU
61  *   HKCR
62  *   HKPD
63  *   HKPT
64  */
65
66 int samba3_upgrade_registry(struct samba3_regdb *regdb, const char *prefix, struct ldb_context *ldb, struct ldb_message ***msgs)
67 {
68         int i;
69         struct ldb_message *msg;
70         int count = 0;
71         char *prefix_up = strupper_talloc(ldb, prefix);
72         *msgs = NULL;
73
74         for (i = 0; i < regdb->key_count; i++) {
75                 int j;
76                 struct samba3_regkey *rk = &regdb->keys[i];
77                 struct ldb_dn *keydn;
78
79                 /* Only handle selected hive */
80                 if (strncmp(prefix_up, rk->name, strlen(prefix_up)) != 0) {
81                         continue;
82                 }
83
84                 msg = msg_array_add(ldb, msgs, &count);
85
86                 msg->num_elements = 0;
87                 msg->elements = NULL;
88                 msg->private_data = NULL;
89
90                 /* Convert key name to dn */
91                 keydn = msg->dn = regkey_to_dn(ldb, rk->name);
92
93                 ldb_msg_add_string(ldb, msg, "name", strrchr(rk->name, '/')?strrchr(rk->name, '/')+1:rk->name);
94                 
95                 for (j = 0; j < rk->value_count; j++) {
96                         struct samba3_regval *rv = &rk->values[j];
97
98                         msg = msg_array_add(ldb, msgs, &count);
99                         msg->dn = ldb_dn_build_child(ldb, "value", rv->name, keydn);
100
101                         ldb_msg_add_string(ldb, msg, "value", rv->name);
102                         ldb_msg_add_fmt(ldb, msg, "type", "%d", rv->type);
103                         ldb_msg_add_value(ldb, msg, "data", &rv->data);
104                 }
105         }
106         
107         talloc_free(prefix_up);
108
109         return count;
110 }
111
112 int samba3_upgrade_sam(struct samba3 *samba3, struct ldb_context *ldb, struct ldb_message ***msgs)
113 {
114         int count = 0;
115         struct ldb_message *msg;
116         struct ldb_dn *domaindn = NULL;
117         const char *domainname;
118         struct samba3_domainsecrets *domsec;
119         int i;
120         *msgs = NULL;
121
122         domainname = samba3_get_param(samba3, "global", "workgroup");
123
124         if (domainname == NULL) {
125                 DEBUG(0, ("No domain name specified in smb.conf!\n"));
126                 return -1;
127         }
128
129         domsec = samba3_find_domainsecrets(samba3, domainname);
130
131         /* Domain */    
132         msg = msg_array_add(ldb, msgs, &count);
133         /* FIXME: Guess domain DN by taking ldap bind dn? */
134
135         ldb_msg_add_string(ldb, msg, "objectClass", "top");
136         ldb_msg_add_string(ldb, msg, "objectClass", "domain");
137         ldb_msg_add_string(ldb, msg, "objectSid", dom_sid_string(msg, &domsec->sid));
138         ldb_msg_add_string(ldb, msg, "objectGUID", GUID_string(msg, &domsec->guid));
139         ldb_msg_add_string(ldb, msg, "name", domainname);
140         ldb_msg_add_string(ldb, msg, "oEMInformation", "Provisioned by Samba4 (upgraded from Samba3)");
141
142         /* account policy as well */
143
144         ldb_msg_add_fmt(ldb, msg, "minPwdLength", "%d", samba3->policy.min_password_length);
145         ldb_msg_add_fmt(ldb, msg, "pwdHistoryLength", "%d", samba3->policy.password_history);
146         ldb_msg_add_fmt(ldb, msg, "minPwdAge", "%d", samba3->policy.minimum_password_age);
147         ldb_msg_add_fmt(ldb, msg, "maxPwdAge", "%d", samba3->policy.maximum_password_age);
148         ldb_msg_add_fmt(ldb, msg, "lockoutDuration", "%d", samba3->policy.lockout_duration);
149         ldb_msg_add_fmt(ldb, msg, "samba3ResetCountMinutes", "%d", samba3->policy.reset_count_minutes);
150         ldb_msg_add_fmt(ldb, msg, "samba3UserMustLogonToChangePassword", "%d", samba3->policy.user_must_logon_to_change_password);
151         ldb_msg_add_fmt(ldb, msg, "samba3BadLockoutMinutes", "%d", samba3->policy.bad_lockout_minutes);
152         ldb_msg_add_fmt(ldb, msg, "samba3DisconnectTime", "%d", samba3->policy.disconnect_time);
153         ldb_msg_add_fmt(ldb, msg, "samba3RefuseMachinePwdChange", "%d", samba3->policy.refuse_machine_password_change);
154         
155         /* Users */
156         for (i = 0; i < samba3->samaccount_count; i++) {
157                 struct samba3_samaccount *sam = &samba3->samaccounts[i];
158
159                 msg = msg_array_add(ldb, msgs, &count);
160                 msg->dn = ldb_dn_build_child(msg, "cn", sam->fullname, domaindn);
161
162                 ldb_msg_add_string(ldb, msg, "objectClass", "top");
163                 ldb_msg_add_string(ldb, msg, "objectClass", "person");
164                 ldb_msg_add_string(ldb, msg, "objectClass", "user");
165                 ldb_msg_add_fmt(ldb, msg, "lastLogon", "%d", sam->logon_time);
166                 ldb_msg_add_fmt(ldb, msg, "lastLogoff", "%d", sam->logoff_time);
167                 ldb_msg_add_string(ldb, msg, "unixName", sam->username);
168                 ldb_msg_add_string(ldb, msg, "name", sam->nt_username);
169                 ldb_msg_add_string(ldb, msg, "cn", sam->fullname);
170                 ldb_msg_add_string(ldb, msg, "description", sam->acct_desc);
171                 ldb_msg_add_fmt(ldb, msg, "primaryGroupID", "%d", sam->group_rid); 
172                 ldb_msg_add_fmt(ldb, msg, "badPwdcount", "%d", sam->bad_password_count);
173                 ldb_msg_add_fmt(ldb, msg, "logonCount", "%d", sam->logon_count);
174                 
175                 ldb_msg_add_string(ldb, msg, "samba3Domain", sam->domain);
176                 if (sam->dir_drive) 
177                         ldb_msg_add_string(ldb, msg, "samba3DirDrive", sam->dir_drive);
178
179                 if (sam->munged_dial)
180                         ldb_msg_add_string(ldb, msg, "samba3MungedDial", sam->munged_dial);
181
182                 if (sam->homedir)
183                         ldb_msg_add_string(ldb, msg, "samba3Homedir", sam->homedir);
184
185                 if (sam->logon_script)
186                         ldb_msg_add_string(ldb, msg, "samba3LogonScript", sam->logon_script);
187
188                 if (sam->profile_path)
189                         ldb_msg_add_string(ldb, msg, "samba3ProfilePath", sam->profile_path);
190
191                 if (sam->workstations)
192                         ldb_msg_add_string(ldb, msg, "samba3Workstations", sam->workstations);
193
194                 ldb_msg_add_fmt(ldb, msg, "samba3KickOffTime", "%d", sam->kickoff_time);
195                 ldb_msg_add_fmt(ldb, msg, "samba3BadPwdTime", "%d", sam->bad_password_time);
196                 ldb_msg_add_fmt(ldb, msg, "samba3PassLastSetTime", "%d", sam->pass_last_set_time);
197                 ldb_msg_add_fmt(ldb, msg, "samba3PassCanChangeTime", "%d", sam->pass_can_change_time);
198                 ldb_msg_add_fmt(ldb, msg, "samba3PassMustChangeTime", "%d", sam->pass_must_change_time);
199                 ldb_msg_add_fmt(ldb, msg, "samba3Rid", "%d", sam->user_rid); 
200         
201                 /* FIXME: Passwords */
202         }
203
204         /* Groups */
205         for (i = 0; i < samba3->group.groupmap_count; i++) {
206                 struct samba3_groupmapping *grp = &samba3->group.groupmappings[i];
207
208                 msg = msg_array_add(ldb, msgs, &count);
209
210                 if (grp->nt_name != NULL) 
211                         msg->dn = ldb_dn_build_child(msg, "cn", grp->nt_name, domaindn);
212                 else 
213                         msg->dn = ldb_dn_build_child(msg, "cn", dom_sid_string(msg, grp->sid), domaindn);
214
215                 ldb_msg_add_string(ldb, msg, "objectClass", "top");
216                 ldb_msg_add_string(ldb, msg, "objectClass", "group");
217                 ldb_msg_add_string(ldb, msg, "description", grp->comment);
218                 ldb_msg_add_string(ldb, msg, "cn", grp->nt_name);
219                 ldb_msg_add_string(ldb, msg, "objectSid", dom_sid_string(msg, grp->sid));
220                 ldb_msg_add_string(ldb, msg, "unixName", "FIXME");
221                 ldb_msg_add_fmt(ldb, msg, "samba3SidNameUse", "%d", grp->sid_name_use);
222         }
223
224         return count;
225 }
226
227 int samba3_upgrade_winbind(struct samba3 *samba3, struct ldb_context *ldb, struct ldb_message ***msgs)
228 {
229         int i;
230         int count = 0;
231         struct ldb_message *msg;
232         struct ldb_dn *basedn = NULL;
233         *msgs = NULL;
234
235         msg = msg_array_add(ldb, msgs, &count);
236
237         msg->dn = basedn; 
238         
239         ldb_msg_add_fmt(ldb, msg, "userHwm", "%d", samba3->idmap.user_hwm);
240         ldb_msg_add_fmt(ldb, msg, "groupHwm", "%d", samba3->idmap.group_hwm);
241
242         for (i = 0; i < samba3->idmap.mapping_count; i++) {
243                 char *sid = dom_sid_string(msg, samba3->idmap.mappings[i].sid);
244                 msg = msg_array_add(ldb, msgs, &count);
245                 
246                 msg->dn = ldb_dn_build_child(ldb, "SID", sid, basedn);
247                 ldb_msg_add_string(ldb, msg, "SID", sid);
248                 ldb_msg_add_fmt(ldb, msg, "type", "%d", samba3->idmap.mappings[i].type);
249                 ldb_msg_add_fmt(ldb, msg, "unixID", "%u", samba3->idmap.mappings[i].unix_id);
250         }
251         
252         return count;
253 }
254
255 int samba3_upgrade_winsdb(struct samba3 *samba3, struct ldb_context *ldb, struct ldb_message ***msgs)
256 {
257         int i;
258         int count = 0;
259         
260         for (i = 0; i < samba3->winsdb_count; i++) {
261                 struct samba3_winsdb_entry *e = &samba3->winsdb_entries[i];
262                 int j;
263                 struct ldb_message *msg = msg_array_add(ldb, msgs, &count);
264
265                 msg->dn = ldb_dn_string_compose(ldb, NULL, "type=%d,name=%s", e->type, e->name);
266
267                 ldb_msg_add_string(ldb, msg, "name", e->name);
268                 ldb_msg_add_fmt(ldb, msg, "type", "%d", e->type);
269                 ldb_msg_add_string(ldb, msg, "objectClass", "wins");
270                 ldb_msg_add_fmt(ldb, msg, "nbFlags", "%x", e->nb_flags);
271                 ldb_msg_add_string(ldb, msg, "expires", 
272                                   ldap_timestring(msg, e->ttl));
273
274                 for (j = 0; j < e->ip_count; j++) {
275                         ldb_msg_add_string(ldb, msg, "address", sys_inet_ntoa(e->ips[j]));
276                 }
277         }
278
279         return count;
280 }