1 
2 /*
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 
25 
26 #include "../includes.h"
27 #include "../trans2.h"
28 #include "../nterr.h"
29 
30 extern int DEBUGLEVEL;
31 
32 extern BOOL sam_logon_in_ssb;
33 extern pstring samlogon_user;
34 
35 #ifdef NTDOMAIN
36 
37 #ifdef USE_ARCFOUR
38 void arcfour(unsigned char data[16], unsigned char data_out[16], unsigned char data_in[16]);
39 #endif
40 
41 /***********************************************************************************
42  make_lsa_r_req_chal:
43  ***********************************************************************************/
make_lsa_r_req_chal(LSA_R_REQ_CHAL * r_c,DOM_CHAL * srv_chal,int status)44 static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c,
45                                 DOM_CHAL *srv_chal, int status)
46 {
47 	DEBUG(6,("make_lsa_r_req_chal: %d\n", __LINE__));
48 	memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
49 	r_c->status = status;
50 }
51 
52 /***********************************************************************************
53  lsa_reply_req_chal:
54  ***********************************************************************************/
lsa_reply_req_chal(LSA_Q_REQ_CHAL * q_c,char * q,char * base,DOM_CHAL * srv_chal,uint32 srv_time)55 static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
56 					DOM_CHAL *srv_chal, uint32 srv_time)
57 {
58 	LSA_R_REQ_CHAL r_c;
59 
60 	DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__));
61 
62 	/* set up the LSA REQUEST CHALLENGE response */
63 	make_lsa_r_req_chal(&r_c, srv_chal, srv_time);
64 
65 	/* store the response in the SMB stream */
66 	q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0);
67 
68 	DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__));
69 
70 	/* return length of SMB data stored */
71 	return PTR_DIFF(q, base);
72 }
73 
74 /***********************************************************************************
75  make_lsa_r_auth_2:
76  ***********************************************************************************/
make_lsa_r_auth_2(LSA_R_AUTH_2 * r_a,DOM_CHAL * resp_cred,NEG_FLAGS * flgs,int status)77 static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
78                               DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
79 {
80 	memcpy(  r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
81 	memcpy(&(r_a->srv_flgs)    , flgs           , sizeof(r_a->srv_flgs));
82 	r_a->status = status;
83 }
84 
85 /***********************************************************************************
86  lsa_reply_auth_2:
87  ***********************************************************************************/
lsa_reply_auth_2(LSA_Q_AUTH_2 * q_a,char * q,char * base,DOM_CHAL * resp_cred,int status)88 static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
89 				DOM_CHAL *resp_cred, int status)
90 {
91 	LSA_R_AUTH_2 r_a;
92 
93 	/* set up the LSA AUTH 2 response */
94 
95 	make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
96 
97 	/* store the response in the SMB stream */
98 	q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0);
99 
100 	/* return length of SMB data stored */
101 	return PTR_DIFF(q, base);
102 }
103 
104 /***********************************************************************************
105  make_lsa_r_srv_pwset:
106  ***********************************************************************************/
make_lsa_r_srv_pwset(LSA_R_SRV_PWSET * r_s,DOM_CRED * srv_cred,int status)107 static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_s,
108                              DOM_CRED *srv_cred, int status)
109 {
110 	DEBUG(5,("make_lsa_r_srv_pwset: %d\n", __LINE__));
111 
112 	memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
113 	r_s->status = status;
114 
115 	DEBUG(5,("make_lsa_r_srv_pwset: %d\n", __LINE__));
116 }
117 
118 /***********************************************************************************
119  lsa_reply_srv_pwset:
120  ***********************************************************************************/
lsa_reply_srv_pwset(LSA_Q_SRV_PWSET * q_s,char * q,char * base,DOM_CRED * srv_cred,int status)121 static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
122 				DOM_CRED *srv_cred, int status)
123 {
124 	LSA_R_SRV_PWSET r_s;
125 
126 	DEBUG(5,("lsa_srv_pwset: %d\n", __LINE__));
127 
128 	/* set up the LSA Server Password Set response */
129 	make_lsa_r_srv_pwset(&r_s, srv_cred, status);
130 
131 	/* store the response in the SMB stream */
132 	q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0);
133 
134 	DEBUG(5,("lsa_srv_pwset: %d\n", __LINE__));
135 
136 	/* return length of SMB data stored */
137 	return PTR_DIFF(q, base);
138 }
139 
140 /***********************************************************************************
141  make_lsa_user_info:
142  ***********************************************************************************/
make_lsa_user_info(LSA_USER_INFO * usr,NTTIME * logon_time,NTTIME * logoff_time,NTTIME * kickoff_time,NTTIME * pass_last_set_time,NTTIME * pass_can_change_time,NTTIME * pass_must_change_time,char * user_name,char * full_name,char * logon_script,char * profile_path,char * home_dir,char * dir_drive,uint16 logon_count,uint16 bad_pw_count,uint32 user_id,uint32 group_id,uint32 num_groups,DOM_GID * gids,uint32 user_flgs,char sess_key[16],char * logon_srv,char * logon_dom,char * dom_sid,char * other_sids)143 static void make_lsa_user_info(LSA_USER_INFO *usr,
144 
145 	NTTIME *logon_time,
146 	NTTIME *logoff_time,
147 	NTTIME *kickoff_time,
148 	NTTIME *pass_last_set_time,
149 	NTTIME *pass_can_change_time,
150 	NTTIME *pass_must_change_time,
151 
152 	char *user_name,
153 	char *full_name,
154 	char *logon_script,
155 	char *profile_path,
156 	char *home_dir,
157 	char *dir_drive,
158 
159 	uint16 logon_count,
160 	uint16 bad_pw_count,
161 
162 	uint32 user_id,
163 	uint32 group_id,
164 	uint32 num_groups,
165 	DOM_GID *gids,
166 	uint32 user_flgs,
167 
168 	char sess_key[16],
169 
170 	char *logon_srv,
171 	char *logon_dom,
172 
173 	char *dom_sid,
174 	char *other_sids) /* space-delimited set of SIDs */
175 {
176 	/* only cope with one "other" sid, right now. */
177 	/* need to count the number of space-delimited sids */
178 	int i;
179 	int num_other_sids = 0;
180 
181 	int len_user_name    = strlen(user_name   );
182 	int len_full_name    = strlen(full_name   );
183 	int len_logon_script = strlen(logon_script);
184 	int len_profile_path = strlen(profile_path);
185 	int len_home_dir     = strlen(home_dir    );
186 	int len_dir_drive    = strlen(dir_drive   );
187 
188 	int len_logon_srv    = strlen(logon_srv);
189 	int len_logon_dom    = strlen(logon_dom);
190 
191 	usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
192 
193 	usr->logon_time            = *logon_time;
194 	usr->logoff_time           = *logoff_time;
195 	usr->kickoff_time          = *kickoff_time;
196 	usr->pass_last_set_time    = *pass_last_set_time;
197 	usr->pass_can_change_time  = *pass_can_change_time;
198 	usr->pass_must_change_time = *pass_must_change_time;
199 
200 	make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   , len_user_name   , 4);
201 	make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   , len_full_name   , 4);
202 	make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
203 	make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
204 	make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    , len_home_dir    , 4);
205 	make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   , len_dir_drive   , 4);
206 
207 	usr->logon_count = logon_count;
208 	usr->bad_pw_count = bad_pw_count;
209 
210 	usr->user_id = user_id;
211 	usr->group_id = group_id;
212 	usr->num_groups = num_groups;
213 	usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
214 	usr->user_flgs = user_flgs;
215 
216 	if (sess_key != NULL)
217 	{
218 		memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
219 	}
220 	else
221 	{
222 		bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
223 	}
224 
225 	make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
226 	make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
227 
228 	usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
229 
230 	bzero(usr->padding, sizeof(usr->padding));
231 
232 	num_other_sids = make_dom_sids(other_sids, usr->other_sids, LSA_MAX_SIDS);
233 
234 	usr->num_other_sids = num_other_sids;
235 	usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
236 
237 	make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
238 	make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
239 	make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
240 	make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
241 	make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
242 	make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
243 
244 	usr->num_groups2 = num_groups;
245 	for (i = 0; i < num_groups; i++)
246 	{
247 		usr->gids[i] = gids[i];
248 	}
249 
250 	make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
251 	make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
252 
253 	make_dom_sid(&(usr->dom_sid), dom_sid);
254 	/* "other" sids are set up above */
255 }
256 
257 
258 /***********************************************************************************
259  lsa_reply_sam_logon:
260  ***********************************************************************************/
lsa_reply_sam_logon(LSA_Q_SAM_LOGON * q_s,char * q,char * base,DOM_CRED * srv_cred,LSA_USER_INFO * user_info)261 static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
262 				DOM_CRED *srv_cred, LSA_USER_INFO *user_info)
263 {
264 	LSA_R_SAM_LOGON r_s;
265 
266 	/* XXXX maybe we want to say 'no', reject the client's credentials */
267 	r_s.buffer_creds = 1; /* yes, we have valid server credentials */
268 	memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
269 
270 	/* store the user information, if there is any. */
271 	r_s.user = user_info;
272 	if (user_info != NULL && user_info->ptr_user_info != 0)
273 	{
274 		r_s.switch_value = 3; /* indicates type of validation user info */
275 		r_s.status = 0;
276 	}
277 	else
278 	{
279 		r_s.switch_value = 0; /* don't know what this value is supposed to be */
280 		r_s.status = 0xC000000|NT_STATUS_NO_SUCH_USER;
281 	}
282 
283 	r_s.auth_resp = 1; /* authoritative response */
284 
285 	/* store the response in the SMB stream */
286 	q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0);
287 
288 	/* return length of SMB data stored */
289 	return PTR_DIFF(q, base);
290 }
291 
292 
293 /***********************************************************************************
294  lsa_reply_sam_logoff:
295  ***********************************************************************************/
lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF * q_s,char * q,char * base,DOM_CRED * srv_cred,uint32 status)296 static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
297 				DOM_CRED *srv_cred,
298 				uint32 status)
299 {
300 	LSA_R_SAM_LOGOFF r_s;
301 
302 	/* XXXX maybe we want to say 'no', reject the client's credentials */
303 	r_s.buffer_creds = 1; /* yes, we have valid server credentials */
304 	memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
305 
306 	r_s.status = status;
307 
308 	/* store the response in the SMB stream */
309 	q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0);
310 
311 	/* return length of SMB data stored */
312 	return PTR_DIFF(q, base);
313 }
314 
315 /****************************************************************************
316   gets a machine password entry.  checks access rights of the host.
317 ****************************************************************************/
get_md4pw(char * md4pw,char * mach_name,char * mach_acct)318 static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
319 {
320     struct smb_passwd *smb_pass;
321 
322 	if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
323 	                  client_name(), client_addr()))
324 	{
325 		DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
326 		return False;
327 	}
328 
329 	become_root(True);
330 	smb_pass = get_smbpwd_entry(mach_acct, 0);
331 	unbecome_root(True);
332 
333 	if (smb_pass != NULL)
334 	{
335 		memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
336 		dump_data(5, md4pw, 16);
337 
338 		return True;
339 	}
340 	DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
341 	return False;
342 }
343 
344 /***********************************************************************************
345  api_lsa_req_chal
346  ***********************************************************************************/
api_lsa_req_chal(int cnum,uint16 vuid,user_struct * vuser,char * param,char * data,char ** rdata,int * rdata_len)347 static void api_lsa_req_chal( int cnum, uint16 vuid,
348                               user_struct *vuser,
349                               char *param, char *data,
350                               char **rdata, int *rdata_len )
351 {
352 	LSA_Q_REQ_CHAL q_r;
353 	uint32 status = 0x0;
354 
355 	fstring mach_acct;
356 	fstring mach_name;
357 
358 	/* grab the challenge... */
359 	lsa_io_q_req_chal(True, &q_r, data + 0x18, data, 4, 0);
360 
361 	fstrcpy(mach_acct, unistrn2(q_r.uni_logon_clnt.buffer,
362 	                            q_r.uni_logon_clnt.uni_str_len));
363 
364 	fstrcpy(mach_name, mach_acct);
365 	strlower(mach_name);
366 
367 	fstrcat(mach_acct, "$");
368 
369 	if (get_md4pw(vuser->dc.md4pw, mach_name, mach_acct))
370 	{
371 		/* copy the client credentials */
372 		memcpy(vuser->dc.clnt_chal.data          , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
373 		memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
374 
375 		/* create a server challenge for the client */
376 		/* PAXX: set these to random values. */
377 		/* lkcl: paul, you mentioned that it doesn't really matter much */
378 		SIVAL(vuser->dc.srv_chal.data, 0, 0x11111111);
379 		SIVAL(vuser->dc.srv_chal.data, 4, 0x11111111);
380 		memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
381 
382 		/* from client / server challenges and md4 password, generate sess key */
383 		cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
384 						   vuser->dc.md4pw, vuser->dc.sess_key);
385 	}
386 	else
387 	{
388 		/* lkclXXXX take a guess at a good error message to return :-) */
389 		status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
390 	}
391 
392 	/* construct reply. */
393 	*rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata,
394 					&(vuser->dc.srv_chal), status);
395 
396 }
397 
398 /***********************************************************************************
399  api_lsa_auth_2:
400  ***********************************************************************************/
api_lsa_auth_2(user_struct * vuser,char * param,char * data,char ** rdata,int * rdata_len)401 static void api_lsa_auth_2( user_struct *vuser,
402                             char *param, char *data,
403                             char **rdata, int *rdata_len )
404 {
405 	LSA_Q_AUTH_2 q_a;
406 
407 	DOM_CHAL srv_cred;
408 	UTIME srv_time;
409 
410 	srv_time.time = 0;
411 
412 	/* grab the challenge... */
413 	lsa_io_q_auth_2(True, &q_a, data + 0x18, data, 4, 0);
414 
415 	/* check that the client credentials are valid */
416 	cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
417                 &(vuser->dc.clnt_cred.challenge), srv_time);
418 
419 	/* create server challenge for inclusion in the reply */
420 	cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
421 
422 	/* copy the received client credentials for use next time */
423 	memcpy(vuser->dc.clnt_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
424 	memcpy(vuser->dc.srv_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
425 
426 	/* construct reply. */
427 	*rdata_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata,
428 					&srv_cred, 0x0);
429 }
430 
431 
432 /***********************************************************************************
433  api_lsa_srv_pwset:
434  ***********************************************************************************/
api_lsa_srv_pwset(user_struct * vuser,char * param,char * data,char ** rdata,int * rdata_len)435 static void api_lsa_srv_pwset( user_struct *vuser,
436                                char *param, char *data,
437                                char **rdata, int *rdata_len )
438 {
439 #ifdef USE_ARCFOUR
440 	char pwd[16];
441 #endif
442 
443 	LSA_Q_SRV_PWSET q_a;
444 	uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
445 	DOM_CRED srv_cred;
446 	pstring mach_acct;
447 	struct smb_passwd *smb_pass;
448 	BOOL ret;
449 
450 	/* grab the challenge and encrypted password ... */
451 	lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data, 4, 0);
452 
453 	/* checks and updates credentials.  creates reply credentials */
454 	if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
455 	                &(q_a.clnt_id.cred), &srv_cred))
456 	{
457 		memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
458 
459 		DEBUG(5,("api_lsa_srv_pwset: %d\n", __LINE__));
460 
461 		pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
462 									q_a.clnt_id.login.uni_acct_name.uni_str_len));
463 
464 		DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
465 
466 		become_root(True);
467 		smb_pass = get_smbpwd_entry(mach_acct, 0);
468 		unbecome_root(True);
469 
470 #ifdef USE_ARCFOUR
471 		if (smb_pass != NULL)
472 		{
473 			unsigned char arc4_key[16];
474 			memset(arc4_key, 0, 16);
475 			memcpy(arc4_key, vuser->dc.sess_key, 8);
476 
477 			arcfour(arc4_key, pwd, q_a.pwd);
478 
479 #ifdef DEBUG_PASSWORD
480 			DEBUG(100,("arcfour decrypt of machine password:"));
481 			dump_data(100, pwd, 16);
482 #endif
483 
484 			/* lies!  nt and lm passwords are _not_ the same: don't care */
485 			smb_pass->smb_passwd    = pwd;
486 			smb_pass->smb_nt_passwd = pwd;
487 
488 			become_root(True);
489 			ret = mod_smbpwd_entry(smb_pass);
490 			unbecome_root(True);
491 
492 			if (ret)
493 			{
494 				/* hooray! */
495 				status = 0x0;
496 			}
497 		}
498 #else
499 		/* sorry.  have to refuse the password change.
500 		   this _is_ ok, because NT accepts this, and the
501 		   machine password stays at its default value..
502 		 */
503 #endif
504 
505 		DEBUG(5,("api_lsa_srv_pwset: %d\n", __LINE__));
506 	}
507 	else
508 	{
509 		/* lkclXXXX take a guess at a sensible error code to return... */
510 		status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
511 	}
512 
513 	/* construct reply.  always indicate failure.  nt keeps going... */
514 	*rdata_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata,
515 					&srv_cred, status);
516 }
517 
518 
519 /***********************************************************************************
520  api_lsa_sam_logoff:
521  ***********************************************************************************/
api_lsa_sam_logoff(user_struct * vuser,char * param,char * data,char ** rdata,int * rdata_len)522 static void api_lsa_sam_logoff( user_struct *vuser,
523                                char *param, char *data,
524                                char **rdata, int *rdata_len )
525 {
526 	LSA_Q_SAM_LOGOFF q_l;
527 	DOM_ID_INFO_1 id1;
528 
529 	DOM_CRED srv_cred;
530 
531 	/* the DOM_ID_INFO_1 structure is a bit big.  plus we might want to
532 	   dynamically allocate it inside lsa_io_q_sam_logon, at some point */
533 	q_l.sam_id.auth.id1 = &id1;
534 
535 	/* grab the challenge... */
536 	lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data, 4, 0);
537 
538 	/* checks and updates credentials.  creates reply credentials */
539 	deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
540 	                &(q_l.sam_id.client.cred), &srv_cred);
541 	memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
542 
543 	/* construct reply.  always indicate success */
544 	*rdata_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata,
545 					&srv_cred,
546 	                0x0);
547 }
548 
549 
550 /***********************************************************************************
551  api_lsa_sam_logon:
552  ***********************************************************************************/
api_lsa_sam_logon(user_struct * vuser,char * param,char * data,char ** rdata,int * rdata_len)553 static void api_lsa_sam_logon( user_struct *vuser,
554                                char *param, char *data,
555                                char **rdata, int *rdata_len )
556 {
557 	LSA_Q_SAM_LOGON q_l;
558 	DOM_ID_INFO_1 id1;
559 	LSA_USER_INFO usr_info;
560 
561 	DOM_CRED srv_cred;
562 
563 	/* the DOM_ID_INFO_1 structure is a bit big.  plus we might want to
564 	   dynamically allocate it inside lsa_io_q_sam_logon, at some point */
565 	q_l.sam_id.auth.id1 = &id1;
566 
567 	lsa_io_q_sam_logon(True, &q_l, data + 0x18, data, 4, 0);
568 
569 	/* checks and updates credentials.  creates reply credentials */
570 	deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
571 	                &(q_l.sam_id.client.cred), &srv_cred);
572 	memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
573 
574 	if (vuser != NULL)
575 	{
576 		DOM_GID gids[LSA_MAX_GROUPS];
577 		int num_gids = 0;
578 		NTTIME dummy_time;
579 		pstring logon_script;
580 		pstring profile_path;
581 		pstring home_dir;
582 		pstring home_drive;
583 		pstring my_name;
584 		pstring my_workgroup;
585 		pstring domain_groups;
586 		pstring dom_sid;
587 		pstring other_sids;
588 		fstring tmp;
589 		extern pstring myname;
590 		uint32 r_uid;
591 		uint32 r_gid;
592 		UNISTR2 *uni_samlogon_user = &(q_l.sam_id.auth.id1->uni_user_name);
593 	    struct smb_passwd *smb_pass;
594 		BOOL pwd_ok = False;
595 
596 #ifdef USE_ARCFOUR
597 		char nt_pwd[16];
598 		char lm_pwd[16];
599 #endif
600 
601 		/* set up pointer indicating user/password failed to be found */
602 		usr_info.ptr_user_info = 0;
603 
604 		dummy_time.low  = 0xffffffff;
605 		dummy_time.high = 0x7fffffff;
606 
607 		get_myname(myname, NULL);
608 
609 		pstrcpy(samlogon_user, unistrn2(uni_samlogon_user->buffer,
610 		                                uni_samlogon_user->uni_str_len));
611 
612 		DEBUG(3,("SAM Logon. Domain:[%s].  User:[%s]\n",
613 		          lp_workgroup(), samlogon_user));
614 
615 		become_root(True);
616 		smb_pass = get_smbpwd_entry(samlogon_user, 0);
617 		unbecome_root(True);
618 
619 #ifdef USE_ARCFOUR
620 		if (smb_pass != NULL)
621 		{
622 			unsigned char arc4_key[16];
623 			memset(arc4_key, 0, 16);
624 			memcpy(arc4_key, vuser->dc.sess_key, 8);
625 
626 			arcfour(arc4_key, lm_pwd, q_l.sam_id.auth.id1->arc4_lm_owf.data);
627 			arcfour(arc4_key, nt_pwd, q_l.sam_id.auth.id1->arc4_nt_owf.data);
628 
629 #ifdef DEBUG_PASSWORD
630 			DEBUG(100,("arcfour decrypt of lm owf password:"));
631 			dump_data(100, lm_pwd, 16);
632 
633 			DEBUG(100,("arcfour decrypt of nt owf password:"));
634 			dump_data(100, nt_pwd, 16);
635 #endif
636 
637 			pwd_ok = memcmp(smb_pass->smb_passwd   , lm_pwd, 16) == 0 ||
638 			         memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) == 0;
639 		}
640 #else
641 		/* sorry.  have to assume that the password is always ok.
642 		   this _is_ ok, because the LSA SAM Logon is nothing to do
643 		   with SMB connections to shares.
644 		 */
645 		pwd_ok = True;
646 #endif
647 
648 		if (smb_pass != NULL && pwd_ok)
649 		{
650 			/* hack to get standard_sub_basic() to use the sam logon username */
651 			sam_logon_in_ssb = True;
652 
653 			pstrcpy(logon_script, lp_logon_script     ());
654 			pstrcpy(profile_path, lp_logon_path       ());
655 			pstrcpy(dom_sid     , lp_domain_sid       ());
656 			pstrcpy(other_sids  , lp_domain_other_sids());
657 			pstrcpy(my_workgroup, lp_workgroup        ());
658 
659 			pstrcpy(home_drive  , lp_logon_drive      ());
660 			pstrcpy(home_dir    , lp_logon_home       ());
661 
662 			pstrcpy(my_name     , myname                );
663 			strupper(my_name);
664 
665 			/* any additional groups this user is in.  e.g power users */
666 			pstrcpy(domain_groups, lp_domain_groups());
667 
668 			/* can only be a user or a guest.  cannot be guest _and_ admin */
669 			if (user_in_list(samlogon_user, lp_domain_guest_users()))
670 			{
671 				slprintf(tmp, sizeof(tmp)-1," %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
672 				pstrcat(domain_groups, tmp);
673 
674 				DEBUG(3,("domain guest access %s granted\n", tmp));
675 			}
676 			else
677 			{
678 				slprintf(tmp, sizeof(tmp)-1, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
679 				fstrcat(domain_groups, tmp);
680 
681 				DEBUG(3,("domain user access %s granted\n", tmp));
682 
683 				if (user_in_list(samlogon_user, lp_domain_admin_users()))
684 				{
685 					slprintf(tmp, sizeof(tmp)-1," %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
686 					pstrcat(domain_groups, tmp);
687 
688 					DEBUG(3,("domain admin access %s granted\n", tmp));
689 				}
690 			}
691 
692 			num_gids = make_dom_gids(domain_groups, gids);
693 
694 			sam_logon_in_ssb = False;
695 		}
696 
697 		if (pwd_ok && name_to_rid(samlogon_user, &r_uid, &r_gid))
698 		{
699 			make_lsa_user_info(&usr_info,
700 
701 		               &dummy_time, /* logon_time */
702 		               &dummy_time, /* logoff_time */
703 		               &dummy_time, /* kickoff_time */
704 		               &dummy_time, /* pass_last_set_time */
705 		               &dummy_time, /* pass_can_change_time */
706 		               &dummy_time, /* pass_must_change_time */
707 
708 		               samlogon_user, /* user_name */
709 		               vuser->real_name, /* full_name */
710 		               logon_script, /* logon_script */
711 		               profile_path, /* profile_path */
712 		               home_dir, /* home_dir */
713 		               home_drive, /* dir_drive */
714 
715 		               0, /* logon_count */
716 		               0, /* bad_pw_count */
717 
718 		               r_uid, /* RID user_id */
719 		               r_gid, /* RID group_id */
720 		               num_gids,    /* uint32 num_groups */
721 		               gids, /* DOM_GID *gids */
722 		               0x20, /* uint32 user_flgs */
723 
724 		               NULL, /* char sess_key[16] */
725 
726 		               my_name     , /* char *logon_srv */
727 		               my_workgroup, /* char *logon_dom */
728 
729 		               dom_sid,     /* char *dom_sid */
730 		               other_sids); /* char *other_sids */
731 		}
732 	}
733 
734 
735 	*rdata_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata,
736 					&srv_cred, &usr_info);
737 }
738 
739 
740 /***********************************************************************************
741  api_netlogrpcTNP:
742  ***********************************************************************************/
api_netlogrpcTNP(int cnum,int uid,char * param,char * data,int mdrcnt,int mprcnt,char ** rdata,char ** rparam,int * rdata_len,int * rparam_len)743 BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
744 		     int mdrcnt,int mprcnt,
745 		     char **rdata,char **rparam,
746 		     int *rdata_len,int *rparam_len)
747 {
748 	user_struct *vuser;
749 
750 	RPC_HDR_RR hdr;
751 
752 	if (data == NULL)
753 	{
754 		DEBUG(2,("api_netlogrpcTNP: NULL data received\n"));
755 		return False;
756 	}
757 
758 	smb_io_rpc_hdr_rr(True, &hdr, data, data, 4, 0);
759 
760 	DEBUG(4,("netlogon TransactNamedPipe op %x\n",hdr.opnum));
761 
762 	if ((vuser = get_valid_user_struct(uid)) == NULL) return False;
763 
764 	DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
765 
766 	switch (hdr.opnum)
767 	{
768 		case LSA_REQCHAL:
769 		{
770 			DEBUG(3,("LSA_REQCHAL\n"));
771 			api_lsa_req_chal(cnum, uid, vuser, param, data, rdata, rdata_len);
772 			create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
773 			break;
774 		}
775 
776 		case LSA_AUTH2:
777 		{
778 			DEBUG(3,("LSA_AUTH2\n"));
779 			api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
780 			create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
781 			break;
782 		}
783 
784 		case LSA_SRVPWSET:
785 		{
786 			DEBUG(3,("LSA_SRVPWSET\n"));
787 			api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
788 			create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
789 			break;
790 		}
791 
792 		case LSA_SAMLOGON:
793 		{
794 			DEBUG(3,("LSA_SAMLOGON\n"));
795 			api_lsa_sam_logon(vuser, param, data, rdata, rdata_len);
796 			create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
797 			break;
798 		}
799 
800 		case LSA_SAMLOGOFF:
801 		{
802 			DEBUG(3,("LSA_SAMLOGOFF\n"));
803 			api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len);
804 			create_rpc_reply(hdr.hdr.call_id, *rdata, *rdata_len);
805 			break;
806 		}
807 
808 		default:
809 		{
810   			DEBUG(4, ("**** netlogon, unknown code: %lx\n", hdr.opnum));
811 			break;
812 		}
813 	}
814 
815 	return True;
816 }
817 
818 #endif /* NTDOMAIN */
819