WHATSNEW: Start WHATSNEW for 3.3.0pre1.
[Samba.git] / source / rpc_client / init_netlogon.c
blob61841953fc61de6d6e8ebc2071711b9629ee5296
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Guenther Deschner 2008.
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/>.
20 #include "includes.h"
22 /*******************************************************************
23 inits a structure.
24 ********************************************************************/
26 void init_netr_SamBaseInfo(struct netr_SamBaseInfo *r,
27 NTTIME last_logon,
28 NTTIME last_logoff,
29 NTTIME acct_expiry,
30 NTTIME last_password_change,
31 NTTIME allow_password_change,
32 NTTIME force_password_change,
33 const char *account_name,
34 const char *full_name,
35 const char *logon_script,
36 const char *profile_path,
37 const char *home_directory,
38 const char *home_drive,
39 uint16_t logon_count,
40 uint16_t bad_password_count,
41 uint32_t rid,
42 uint32_t primary_gid,
43 struct samr_RidWithAttributeArray groups,
44 uint32_t user_flags,
45 struct netr_UserSessionKey key,
46 const char *logon_server,
47 const char *domain,
48 struct dom_sid2 *domain_sid,
49 struct netr_LMSessionKey LMSessKey,
50 uint32_t acct_flags)
52 r->last_logon = last_logon;
53 r->last_logoff = last_logoff;
54 r->acct_expiry = acct_expiry;
55 r->last_password_change = last_password_change;
56 r->allow_password_change = allow_password_change;
57 r->force_password_change = force_password_change;
58 init_lsa_String(&r->account_name, account_name);
59 init_lsa_String(&r->full_name, full_name);
60 init_lsa_String(&r->logon_script, logon_script);
61 init_lsa_String(&r->profile_path, profile_path);
62 init_lsa_String(&r->home_directory, home_directory);
63 init_lsa_String(&r->home_drive, home_drive);
64 r->logon_count = logon_count;
65 r->bad_password_count = bad_password_count;
66 r->rid = rid;
67 r->primary_gid = primary_gid;
68 r->groups = groups;
69 r->user_flags = user_flags;
70 r->key = key;
71 init_lsa_StringLarge(&r->logon_server, logon_server);
72 init_lsa_StringLarge(&r->domain, domain);
73 r->domain_sid = domain_sid;
74 r->LMSessKey = LMSessKey;
75 r->acct_flags = acct_flags;
78 /*******************************************************************
79 inits a structure.
80 ********************************************************************/
82 void init_netr_SamInfo3(struct netr_SamInfo3 *r,
83 NTTIME last_logon,
84 NTTIME last_logoff,
85 NTTIME acct_expiry,
86 NTTIME last_password_change,
87 NTTIME allow_password_change,
88 NTTIME force_password_change,
89 const char *account_name,
90 const char *full_name,
91 const char *logon_script,
92 const char *profile_path,
93 const char *home_directory,
94 const char *home_drive,
95 uint16_t logon_count,
96 uint16_t bad_password_count,
97 uint32_t rid,
98 uint32_t primary_gid,
99 struct samr_RidWithAttributeArray groups,
100 uint32_t user_flags,
101 struct netr_UserSessionKey key,
102 const char *logon_server,
103 const char *domain,
104 struct dom_sid2 *domain_sid,
105 struct netr_LMSessionKey LMSessKey,
106 uint32_t acct_flags,
107 uint32_t sidcount,
108 struct netr_SidAttr *sids)
110 init_netr_SamBaseInfo(&r->base,
111 last_logon,
112 last_logoff,
113 acct_expiry,
114 last_password_change,
115 allow_password_change,
116 force_password_change,
117 account_name,
118 full_name,
119 logon_script,
120 profile_path,
121 home_directory,
122 home_drive,
123 logon_count,
124 bad_password_count,
125 rid,
126 primary_gid,
127 groups,
128 user_flags,
129 key,
130 logon_server,
131 domain,
132 domain_sid,
133 LMSessKey,
134 acct_flags);
135 r->sidcount = sidcount;
136 r->sids = sids;
139 /*******************************************************************
140 gets a domain user's groups from their already-calculated NT_USER_TOKEN
141 ********************************************************************/
143 static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
144 const DOM_SID *domain_sid,
145 size_t num_sids,
146 const DOM_SID *sids,
147 int *numgroups, DOM_GID **pgids)
149 int i;
151 *numgroups=0;
152 *pgids = NULL;
154 for (i=0; i<num_sids; i++) {
155 DOM_GID gid;
156 if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.g_rid)) {
157 continue;
159 gid.attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
160 SE_GROUP_ENABLED);
161 ADD_TO_ARRAY(mem_ctx, DOM_GID, gid, pgids, numgroups);
162 if (*pgids == NULL) {
163 return NT_STATUS_NO_MEMORY;
166 return NT_STATUS_OK;
169 /****************************************************************************
170 inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
171 already be initialized and is used as the talloc parent for its members.
172 *****************************************************************************/
174 NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
175 uint8_t pipe_session_key[16],
176 struct netr_SamInfo3 *sam3)
178 struct samu *sampw;
179 DOM_GID *gids = NULL;
180 const DOM_SID *user_sid = NULL;
181 const DOM_SID *group_sid = NULL;
182 DOM_SID domain_sid;
183 uint32 user_rid, group_rid;
184 NTSTATUS status;
186 int num_gids = 0;
187 const char *my_name;
189 struct netr_UserSessionKey user_session_key;
190 struct netr_LMSessionKey lm_session_key;
192 NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
193 NTTIME allow_password_change, force_password_change;
194 struct samr_RidWithAttributeArray groups;
195 int i;
196 struct dom_sid2 *sid = NULL;
198 ZERO_STRUCT(user_session_key);
199 ZERO_STRUCT(lm_session_key);
201 sampw = server_info->sam_account;
203 user_sid = pdb_get_user_sid(sampw);
204 group_sid = pdb_get_group_sid(sampw);
206 if ((user_sid == NULL) || (group_sid == NULL)) {
207 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
208 return NT_STATUS_UNSUCCESSFUL;
211 sid_copy(&domain_sid, user_sid);
212 sid_split_rid(&domain_sid, &user_rid);
214 sid = sid_dup_talloc(sam3, &domain_sid);
215 if (!sid) {
216 return NT_STATUS_NO_MEMORY;
219 if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
220 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
221 "%s\n but group sid %s.\n"
222 "The conflicting domain portions are not "
223 "supported for NETLOGON calls\n",
224 pdb_get_domain(sampw),
225 pdb_get_username(sampw),
226 sid_string_dbg(user_sid),
227 sid_string_dbg(group_sid)));
228 return NT_STATUS_UNSUCCESSFUL;
231 if(server_info->login_server) {
232 my_name = server_info->login_server;
233 } else {
234 my_name = global_myname();
237 status = nt_token_to_group_list(sam3, &domain_sid,
238 server_info->num_sids,
239 server_info->sids,
240 &num_gids, &gids);
242 if (!NT_STATUS_IS_OK(status)) {
243 return status;
246 if (server_info->user_session_key.length) {
247 memcpy(user_session_key.key,
248 server_info->user_session_key.data,
249 MIN(sizeof(user_session_key.key),
250 server_info->user_session_key.length));
251 SamOEMhash(user_session_key.key, pipe_session_key, 16);
253 if (server_info->lm_session_key.length) {
254 memcpy(lm_session_key.key,
255 server_info->lm_session_key.data,
256 MIN(sizeof(lm_session_key.key),
257 server_info->lm_session_key.length));
258 SamOEMhash(lm_session_key.key, pipe_session_key, 8);
261 groups.count = num_gids;
262 groups.rids = TALLOC_ARRAY(sam3, struct samr_RidWithAttribute, groups.count);
263 if (!groups.rids) {
264 return NT_STATUS_NO_MEMORY;
267 for (i=0; i < groups.count; i++) {
268 groups.rids[i].rid = gids[i].g_rid;
269 groups.rids[i].attributes = gids[i].attr;
272 unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
273 unix_to_nt_time(&last_logoff, get_time_t_max());
274 unix_to_nt_time(&acct_expiry, get_time_t_max());
275 unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
276 unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
277 unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
279 init_netr_SamInfo3(sam3,
280 last_logon,
281 last_logoff,
282 acct_expiry,
283 last_password_change,
284 allow_password_change,
285 force_password_change,
286 talloc_strdup(sam3, pdb_get_username(sampw)),
287 talloc_strdup(sam3, pdb_get_fullname(sampw)),
288 talloc_strdup(sam3, pdb_get_logon_script(sampw)),
289 talloc_strdup(sam3, pdb_get_profile_path(sampw)),
290 talloc_strdup(sam3, pdb_get_homedir(sampw)),
291 talloc_strdup(sam3, pdb_get_dir_drive(sampw)),
292 0, /* logon_count */
293 0, /* bad_password_count */
294 user_rid,
295 group_rid,
296 groups,
297 NETLOGON_EXTRA_SIDS,
298 user_session_key,
299 my_name,
300 talloc_strdup(sam3, pdb_get_domain(sampw)),
301 sid,
302 lm_session_key,
303 pdb_get_acct_ctrl(sampw),
304 0, /* sidcount */
305 NULL); /* struct netr_SidAttr *sids */
306 ZERO_STRUCT(user_session_key);
307 ZERO_STRUCT(lm_session_key);
309 return NT_STATUS_OK;
312 /*******************************************************************
313 inits a structure.
314 ********************************************************************/
316 void init_netr_IdentityInfo(struct netr_IdentityInfo *r,
317 const char *domain_name,
318 uint32_t parameter_control,
319 uint32_t logon_id_low,
320 uint32_t logon_id_high,
321 const char *account_name,
322 const char *workstation)
324 init_lsa_String(&r->domain_name, domain_name);
325 r->parameter_control = parameter_control;
326 r->logon_id_low = logon_id_low;
327 r->logon_id_high = logon_id_high;
328 init_lsa_String(&r->account_name, account_name);
329 init_lsa_String(&r->workstation, workstation);
332 /*******************************************************************
333 inits a structure.
334 This is a network logon packet. The log_id parameters
335 are what an NT server would generate for LUID once the
336 user is logged on. I don't think we care about them.
338 Note that this has no access to the NT and LM hashed passwords,
339 so it forwards the challenge, and the NT and LM responses (24
340 bytes each) over the secure channel to the Domain controller
341 for it to say yea or nay. This is the preferred method of
342 checking for a logon as it doesn't export the password
343 hashes to anyone who has compromised the secure channel. JRA.
345 ********************************************************************/
347 void init_netr_NetworkInfo(struct netr_NetworkInfo *r,
348 const char *domain_name,
349 uint32_t parameter_control,
350 uint32_t logon_id_low,
351 uint32_t logon_id_high,
352 const char *account_name,
353 const char *workstation,
354 uint8_t challenge[8],
355 struct netr_ChallengeResponse nt,
356 struct netr_ChallengeResponse lm)
358 init_netr_IdentityInfo(&r->identity_info,
359 domain_name,
360 parameter_control,
361 logon_id_low,
362 logon_id_high,
363 account_name,
364 workstation);
365 memcpy(r->challenge, challenge, 8);
366 r->nt = nt;
367 r->lm = lm;
370 /*******************************************************************
371 inits a structure.
372 ********************************************************************/
374 void init_netr_PasswordInfo(struct netr_PasswordInfo *r,
375 const char *domain_name,
376 uint32_t parameter_control,
377 uint32_t logon_id_low,
378 uint32_t logon_id_high,
379 const char *account_name,
380 const char *workstation,
381 struct samr_Password lmpassword,
382 struct samr_Password ntpassword)
384 init_netr_IdentityInfo(&r->identity_info,
385 domain_name,
386 parameter_control,
387 logon_id_low,
388 logon_id_high,
389 account_name,
390 workstation);
391 r->lmpassword = lmpassword;
392 r->ntpassword = ntpassword;