654445b31da9054529dc14791e0507cc5a35eddb
[kai/samba.git] / source / rpc_client / cli_netlogon.c
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 #ifdef SYSLOG
27 #undef SYSLOG
28 #endif
29
30 #include "includes.h"
31
32 extern int DEBUGLEVEL;
33
34 /****************************************************************************
35 do a LSA Logon Control2
36 ****************************************************************************/
37
38 BOOL do_net_logon_ctrl2(struct cli_state *cli, uint16 fnum,
39                         char *host_name, uint32 status_level)
40 {
41   prs_struct rbuf;
42   prs_struct buf; 
43   NET_Q_LOGON_CTRL2 q_l;
44   BOOL valid_ctrl2 = False;
45   fstring acct_name;
46
47   if (host_name == NULL)
48     return False;
49
50   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
51   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
52
53   strcpy(acct_name, "\\\\");
54   strcat(acct_name, host_name);
55
56   /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
57
58   DEBUG(4,("LSA Logon Control2 from %s status level:%x\n",
59            host_name, status_level));
60
61   /* store the parameters */
62   make_q_logon_ctrl2(&q_l, acct_name, status_level);
63
64   /* turn parameters into data stream */
65   net_io_q_logon_ctrl2("", &q_l,  &buf, 0);
66
67   /* send the data on \PIPE\ */
68   if (rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &buf, &rbuf))
69   {
70     NET_R_LOGON_CTRL2 r_l;
71     BOOL ok;
72
73     net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
74     ok = (rbuf.offset != 0);
75                 
76     if (ok && r_l.status != 0)
77     {
78       /* report error code */
79       DEBUG(0,("NET_R_LOGON_CTRL: %s\n", get_nt_error_msg(r_l.status)));
80       cli->nt_error = r_l.status;
81       ok = False;
82     }
83
84     if (ok)
85     {
86       valid_ctrl2 = True;
87     }
88   }
89
90   prs_mem_free(&rbuf);
91   prs_mem_free(&buf );
92
93   return valid_ctrl2;
94 }
95
96 /****************************************************************************
97 do a LSA Authenticate 2
98 ****************************************************************************/
99
100 BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan, 
101                    uint32 neg_flags, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
102 {
103   prs_struct rbuf;
104   prs_struct buf; 
105   NET_Q_AUTH_2 q_a;
106   BOOL valid_chal = False;
107
108   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
109   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
110
111   /* create and send a MSRPC command with api NET_AUTH2 */
112
113   DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %lx\n",
114          cli->srv_name, cli->mach_acct, sec_chan, global_myname,
115          credstr(clnt_chal->data), neg_flags));
116
117   /* store the parameters */
118   make_q_auth_2(&q_a, cli->srv_name, cli->mach_acct, sec_chan, global_myname,
119                 clnt_chal, neg_flags);
120
121   /* turn parameters into data stream */
122   net_io_q_auth_2("", &q_a,  &buf, 0);
123
124   /* send the data on \PIPE\ */
125   if (rpc_api_pipe_req(cli, NET_AUTH2, &buf, &rbuf))
126   {
127     NET_R_AUTH_2 r_a;
128     BOOL ok;
129
130     net_io_r_auth_2("", &r_a, &rbuf, 0);
131     ok = (rbuf.offset != 0);
132                 
133     if (ok && r_a.status != 0)
134     {
135       /* report error code */
136       DEBUG(0,("NET_AUTH2: %s\n", get_nt_error_msg(r_a.status)));
137       cli->nt_error = r_a.status;
138       ok = False;
139     }
140
141     if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
142     {
143       /* report different neg_flags */
144       DEBUG(0,("NET_AUTH2: error neg_flags (q,r) differ - (%lx,%lx)\n",
145           q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
146       ok = False;
147     }
148
149     if (ok)
150     {
151       /* ok, at last: we're happy. return the challenge */
152       memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data));
153       valid_chal = True;
154     }
155   }
156
157   prs_mem_free(&rbuf);
158   prs_mem_free(&buf );
159
160   return valid_chal;
161 }
162
163 /****************************************************************************
164 do a LSA Request Challenge
165 ****************************************************************************/
166
167 BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
168 {
169   prs_struct rbuf;
170   prs_struct buf; 
171   NET_Q_REQ_CHAL q_c;
172   BOOL valid_chal = False;
173
174   if (srv_chal == NULL || clnt_chal == NULL)
175     return False;
176
177   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
178   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
179
180   /* create and send a MSRPC command with api NET_REQCHAL */
181
182   DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
183          cli->desthost, global_myname, credstr(clnt_chal->data)));
184
185   /* store the parameters */
186   make_q_req_chal(&q_c, desthost, global_myname, clnt_chal);
187
188   /* turn parameters into data stream */
189   net_io_q_req_chal("", &q_c,  &buf, 0);
190
191   /* send the data on \PIPE\ */
192   if (rpc_api_pipe_req(cli, NET_REQCHAL, &buf, &rbuf))
193   {
194     NET_R_REQ_CHAL r_c;
195     BOOL ok;
196
197     net_io_r_req_chal("", &r_c, &rbuf, 0);
198     ok = (rbuf.offset != 0);
199                 
200     if (ok && r_c.status != 0)
201     {
202       /* report error code */
203       DEBUG(0,("NET_REQ_CHAL: %s\n", get_nt_error_msg(r_c.status)));
204       cli->nt_error = r_a.status;
205       ok = False;
206     }
207
208     if (ok)
209     {
210       /* ok, at last: we're happy. return the challenge */
211       memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data));
212       valid_chal = True;
213     }
214   }
215
216   prs_mem_free(&rbuf);
217   prs_mem_free(&buf );
218
219   return valid_chal;
220 }
221
222 /***************************************************************************
223 do a LSA Server Password Set
224 ****************************************************************************/
225
226 BOOL do_net_srv_pwset(struct cli_state *cli, uint16 fnum,
227                       uchar sess_key[16], DOM_CRED *sto_clnt_cred,
228                       char *logon_srv, char *mach_acct, uint16 sec_chan_type,
229                       char *comp_name, DOM_CRED *clnt_cred, DOM_CRED *srv_cred,
230                       uint8 nt_owf_new_mach_pwd[16])
231 {
232   prs_struct rbuf;
233   prs_struct buf; 
234   NET_Q_SRV_PWSET q_s;
235   BOOL valid_cred = False;
236
237   if (srv_cred == NULL || clnt_cred == NULL)
238     return False;
239
240   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
241   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
242
243
244   /* create and send a MSRPC command with api NET_SRV_PWSET */
245
246   DEBUG(4,("LSA Server Password Set: srv:%s acct:%s sc: %d mc: %s clnt %s %lx\n",
247            logon_srv, mach_acct, sec_chan_type, comp_name,
248            credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time));
249
250   /* store the parameters */
251   make_q_srv_pwset(&q_s, sess_key, logon_srv, mach_acct, sec_chan_type,
252                    comp_name, clnt_cred, nt_owf_new_mach_pwd);
253
254   /* turn parameters into data stream */
255   net_io_q_srv_pwset("", &q_s,  &buf, 0);
256
257   /* send the data on \PIPE\ */
258   if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
259   {
260     NET_R_SRV_PWSET r_s;
261     BOOL ok;
262
263     net_io_r_srv_pwset("", &r_s, &rbuf, 0);
264     ok = (rbuf.offset != 0);
265                 
266     if (ok && r_s.status != 0)
267     {
268       /* report error code */
269       DEBUG(0,("NET_R_SRV_PWSET: %s\n", get_nt_error_msg(r_s.status)));
270       cli->nt_error = r_s.status;
271       ok = False;
272     }
273
274     if (ok)
275     {
276       if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_cred)))
277       {
278         DEBUG(5, ("do_net_srv_pwset: server credential check OK\n"));
279         /* ok, at last: we're happy. return the challenge */
280         memcpy(srv_cred, &(r_s.srv_cred), sizeof(r_s.srv_cred));
281         valid_cred = True;
282       }
283       else
284       {
285         DEBUG(5, ("do_net_srv_pwset: server credential check failed\n"));
286       }
287     }
288   }
289
290   prs_mem_free(&rbuf);
291   prs_mem_free(&buf );
292
293   return valid_cred;
294 }
295
296 /***************************************************************************
297 do a LSA SAM Logon
298 ****************************************************************************/
299
300 BOOL cli_net_sam_logon(struct cli_state *cli, DOM_CRED *sto_clnt_cred,
301                       char *logon_srv, char *comp_name,
302                       DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
303                       uint16 logon_level, NET_ID_INFO_CTR *ctr,
304                       uint16 validation_level, NET_USER_INFO_3 *user_info3,
305                       DOM_CRED *srv_cred)
306 {
307   prs_struct rbuf;
308   prs_struct buf; 
309   NET_Q_SAM_LOGON q_s;
310   BOOL valid_cred = False;
311
312   if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL || user_info3 == NULL)
313     return False;
314
315   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
316   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
317
318   /* create and send a MSRPC command with api NET_SAMLOGON */
319
320   DEBUG(4,("LSA SAM Logon: srv:%s mc:%s clnt %s %lx rtn: %s %lx ll: %d\n",
321              cli->srv_name, global_myname, 
322              credstr(cli->clnt_cred->challenge.data), cli->clnt_cred->timestamp.time,
323              credstr(rtn_cred->challenge.data), rtn_cred ->timestamp.time,
324              logon_level));
325
326   /* store the parameters */
327   make_sam_info(&(q_s.sam_id), cli->srv_name, global_myname,
328          cli->clnt_cred, rtn_cred, logon_level, ctr, validation_level);
329
330   /* turn parameters into data stream */
331   net_io_q_sam_logon("", &q_s,  &buf, 0);
332
333   /* send the data on \PIPE\ */
334   if (rpc_api_pipe_req(cli, NET_SAMLOGON, &buf, &rbuf))
335   {
336     NET_R_SAM_LOGON r_s;
337     BOOL ok;
338
339     r_s.user = user_info3;
340
341     net_io_r_sam_logon("", &r_s, &rbuf, 0);
342     ok = (rbuf.offset != 0);
343                 
344     if (ok && r_s.status != 0)
345     {
346       /* report error code */
347       DEBUG(0,("NET_SAMLOGON: %s\n", get_nt_error_msg(r_s.status)));
348       cli->nt_error = r_s.status;
349       ok = False;
350     }
351
352     if (ok && r_s.switch_value != 3)
353     {
354       /* report different switch_value */
355       DEBUG(0,("NET_SAMLOGON: switch_value of 3 expected %x\n",
356                    r_s.switch_value));
357       ok = False;
358     }
359
360     if (ok)
361     {
362       if (clnt_deal_with_creds(cli->sess_key, sto_clnt_cred, &(r_s.srv_creds)))
363       {
364         DEBUG(5, ("do_net_sam_logon: server credential check OK\n"));
365         /* ok, at last: we're happy. return the challenge */
366         memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
367         valid_cred = True;
368       }
369       else
370       {
371         DEBUG(5, ("do_net_sam_logon: server credential check failed\n"));
372       }
373     }
374   }
375
376   prs_mem_free(&rbuf);
377   prs_mem_free(&buf );
378
379   return valid_cred;
380 }
381
382 /***************************************************************************
383 do a LSA SAM Logoff
384 ****************************************************************************/
385
386 BOOL do_net_sam_logoff(struct cli_state *cli, uint16 fnum,
387                        uchar sess_key[8], DOM_CRED *sto_clnt_cred,
388                        char *logon_srv, char *comp_name,
389                        DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
390                        uint16 logon_level, NET_ID_INFO_CTR *ctr, 
391                        uint16 validation_level, DOM_CRED *srv_cred)
392 {
393   prs_struct rbuf;
394   prs_struct buf; 
395   NET_Q_SAM_LOGOFF q_s;
396   BOOL valid_cred = False;
397
398   if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL)
399     return False;
400
401   prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
402   prs_init(&rbuf, 0,    4, SAFETY_MARGIN, True );
403
404   /* create and send a MSRPC command with api NET_SAMLOGON */
405
406   DEBUG(4,("LSA SAM Logoff: srv:%s mc:%s clnt %s %lx rtn: %s %lx ll: %d\n",
407             logon_srv, comp_name,
408             credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time,
409             credstr(rtn_cred->challenge.data), rtn_cred ->timestamp.time,
410             logon_level));
411
412   /* store the parameters */
413   make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
414                 clnt_cred, rtn_cred, logon_level, ctr, validation_level);
415
416   /* turn parameters into data stream */
417   net_io_q_sam_logoff("", &q_s,  &buf, 0);
418
419   /* send the data on \PIPE\ */
420   if (rpc_api_pipe_req(cli, NET_SAMLOGOFF, &buf, &rbuf))
421   {
422     NET_R_SAM_LOGOFF r_s;
423     BOOL ok;
424
425     net_io_r_sam_logoff("", &r_s, &rbuf, 0);
426     ok = (rbuf.offset != 0);
427                 
428     if (ok && r_s.status != 0)
429     {
430       /* report error code */
431       DEBUG(0,("NET_SAMLOGOFF: %s\n", get_nt_error_msg(r_s.status)));
432       cli->nt_error = r_s.status;
433       ok = False;
434     }
435
436     if (ok)
437     {
438       if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
439       {
440         DEBUG(5, ("do_net_sam_logoff: server credential check OK\n"));
441         /* ok, at last: we're happy. return the challenge */
442         memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
443         valid_cred = True;
444       }
445       else
446       {
447         DEBUG(5, ("do_net_sam_logoff: server credential check failed\n"));
448       }
449     }
450   }
451
452   prs_mem_free(&rbuf);
453   prs_mem_free(&buf );
454
455   return valid_cred;
456 }