2 Unix SMB/Netbios implementation.
4 Pipe SMB reply routines
5 Copyright (C) Andrew Tridgell 1992-1997,
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
7 Copyright (C) Paul Ashton 1997.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 This file handles reply_ calls on named pipes that the server
25 makes to handle specific protocols
33 #define PIPE "\\PIPE\\"
34 #define PIPELEN strlen(PIPE)
36 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
38 /* look in server.c for some explanation of these variables */
40 extern int DEBUGLEVEL;
41 extern int chain_fnum;
42 extern char magic_char;
43 extern connection_struct Connections[];
44 extern files_struct Files[];
45 extern BOOL case_sensitive;
46 extern pstring sesssetup_user;
48 extern fstring myworkgroup;
50 /* this macro should always be used to extract an fnum (smb_fid) from
51 a packet to ensure chaining works correctly */
52 #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
54 char * known_pipes [] =
63 /****************************************************************************
64 reply to an open and X on a named pipe
66 In fact what we do is to open a regular file with the same name in
67 /tmp. This can then be closed as normal. Reading and writing won't
68 make much sense, but will do *something*. The real reason for this
69 support is to be able to do transactions on them (well, on lsarpc
70 for domain login purposes...).
72 This code is basically stolen from reply_open_and_X with some
73 wrinkles to handle pipes.
74 ****************************************************************************/
75 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
78 int cnum = SVAL(inbuf,smb_tid);
80 int smb_mode = SVAL(inbuf,smb_vwv3);
81 int smb_attr = SVAL(inbuf,smb_vwv5);
83 int open_flags = SVAL(inbuf,smb_vwv2);
84 int smb_sattr = SVAL(inbuf,smb_vwv4);
85 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
87 int smb_ofun = SVAL(inbuf,smb_vwv8);
89 int size=0,fmode=0,mtime=0,rmode=0;
93 BOOL bad_path = False;
95 /* XXXX we need to handle passed times, sattr and flags */
96 pstrcpy(fname,smb_buf(inbuf));
98 /* If the name doesn't start \PIPE\ then this is directed */
99 /* at a mailslot or something we really, really don't understand, */
100 /* not just something we really don't understand. */
101 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
102 return(ERROR(ERRSRV,ERRaccess));
104 DEBUG(4,("Opening pipe %s.\n", fname));
106 /* Strip \PIPE\ off the name. */
107 pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
109 /* See if it is one we want to handle. */
110 for( i = 0; known_pipes[i] ; i++ )
111 if( strcmp(fname,known_pipes[i]) == 0 )
114 if ( known_pipes[i] == NULL )
115 return(ERROR(ERRSRV,ERRaccess));
117 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
118 /* can be opened and add it in after the open. */
119 DEBUG(3,("Known pipe %s opening.\n",fname));
121 Connections[cnum].read_only = 0;
122 smb_ofun |= 0x10; /* Add Create it not exists flag */
124 unix_convert(fname,cnum,0,&bad_path);
126 fnum = find_free_file();
128 return(ERROR(ERRSRV,ERRnofids));
130 if (!check_name(fname,cnum))
131 return(UNIXERROR(ERRDOS,ERRnoaccess));
133 unixmode = unix_mode(cnum,smb_attr);
135 open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
136 0, &rmode,&smb_action);
138 if (!Files[fnum].open)
140 /* Change the error code if bad_path was set. */
141 if((errno == ENOENT) && bad_path)
143 unix_ERR_class = ERRDOS;
144 unix_ERR_code = ERRbadpath;
146 return(UNIXERROR(ERRDOS,ERRnoaccess));
149 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
151 return(ERROR(ERRDOS,ERRnoaccess));
155 fmode = dos_mode(cnum,fname,&sbuf);
156 mtime = sbuf.st_mtime;
159 return(ERROR(ERRDOS,ERRnoaccess));
162 /* Prepare the reply */
163 set_message(outbuf,15,0,True);
165 /* Put things back the way they were. */
166 Connections[cnum].read_only = 1;
168 /* Mark the opened file as an existing named pipe in message mode. */
169 SSVAL(outbuf,smb_vwv9,2);
170 SSVAL(outbuf,smb_vwv10,0xc700);
173 DEBUG(4,("Resetting open result to open from create.\n"));
177 SSVAL(outbuf,smb_vwv2,fnum);
178 SSVAL(outbuf,smb_vwv3,fmode);
179 put_dos_date3(outbuf,smb_vwv4,mtime);
180 SIVAL(outbuf,smb_vwv6,size);
181 SSVAL(outbuf,smb_vwv8,rmode);
182 SSVAL(outbuf,smb_vwv11,smb_action);
186 DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
187 fname, fnum, Files[fnum].name));
189 return chain_reply(inbuf,outbuf,length,bufsize);
193 /****************************************************************************
196 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
197 so just blithely return True. This is really only for NT domain stuff,
198 we we're only handling that - don't assume Samba now does complete
200 ****************************************************************************/
201 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
202 int mdrcnt,int mprcnt,
203 char **rdata,char **rparam,
204 int *rdata_len,int *rparam_len)
208 id = param[0] + (param[1] << 8);
209 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
214 /****************************************************************************
217 TransactNamedPipe on \PIPE\lsarpc.
218 ****************************************************************************/
219 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
221 uint32 dword1, dword2;
222 char pname[] = "\\PIPE\\lsass";
224 /* All kinds of mysterious numbers here */
226 *rdata = REALLOC(*rdata,*rdata_len);
228 dword1 = IVAL(data,0xC);
229 dword2 = IVAL(data,0x10);
231 SIVAL(*rdata,0,0xc0005);
232 SIVAL(*rdata,4,0x10);
233 SIVAL(*rdata,8,0x44);
234 SIVAL(*rdata,0xC,dword1);
236 SIVAL(*rdata,0x10,dword2);
237 SIVAL(*rdata,0x14,0x15);
238 SSVAL(*rdata,0x18,sizeof(pname));
239 strcpy(*rdata + 0x1a,pname);
240 SIVAL(*rdata,0x28,1);
241 memcpy(*rdata + 0x30, data + 0x34, 0x14);
244 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
248 /* All kinds of mysterious numbers here */
250 *rdata = REALLOC(*rdata,*rdata_len);
252 dword1 = IVAL(data,0xC);
254 SIVAL(*rdata,0,0x03020005);
255 SIVAL(*rdata,4,0x10);
256 SIVAL(*rdata,8,0x30);
257 SIVAL(*rdata,0xC,dword1);
258 SIVAL(*rdata,0x10,0x18);
259 SIVAL(*rdata,0x1c,0x44332211);
260 SIVAL(*rdata,0x20,0x88776655);
261 SIVAL(*rdata,0x24,0xCCBBAA99);
262 SIVAL(*rdata,0x28,0x11FFEEDD);
265 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
269 char * workgroup = myworkgroup;
270 int wglen = strlen(workgroup);
273 /* All kinds of mysterious numbers here */
274 *rdata_len = 90 + 2 * wglen;
275 *rdata = REALLOC(*rdata,*rdata_len);
277 dword1 = IVAL(data,0xC);
278 word1 = SVAL(data,0x2C);
280 SIVAL(*rdata,0,0x03020005);
281 SIVAL(*rdata,4,0x10);
282 SIVAL(*rdata,8,0x60);
283 SIVAL(*rdata,0xC,dword1);
284 SIVAL(*rdata,0x10,0x48);
285 SSVAL(*rdata,0x18,0x5988); /* This changes */
286 SSVAL(*rdata,0x1A,0x15);
287 SSVAL(*rdata,0x1C,word1);
288 SSVAL(*rdata,0x20,6);
289 SSVAL(*rdata,0x22,8);
290 SSVAL(*rdata,0x24,0x8E8); /* So does this */
291 SSVAL(*rdata,0x26,0x15);
292 SSVAL(*rdata,0x28,0x4D48); /* And this */
293 SSVAL(*rdata,0x2A,0x15);
294 SIVAL(*rdata,0x2C,4);
295 SIVAL(*rdata,0x34,wglen);
296 for ( i = 0 ; i < wglen ; i++ )
297 (*rdata)[0x38 + i * 2] = workgroup[i];
299 /* Now fill in the rest */
300 i = 0x38 + wglen * 2;
301 SSVAL(*rdata,i,0x648);
303 SIVAL(*rdata,i+6,0x401);
304 SSVAL(*rdata,i+0xC,0x500);
305 SIVAL(*rdata,i+0xE,0x15);
306 SIVAL(*rdata,i+0x12,0x2372FE1);
307 SIVAL(*rdata,i+0x16,0x7E831BEF);
308 SIVAL(*rdata,i+0x1A,0x4B454B2);
311 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
315 /* All kinds of mysterious numbers here */
317 *rdata = REALLOC(*rdata,*rdata_len);
319 dword1 = IVAL(data,0xC);
321 SIVAL(*rdata,0,0x03020005);
322 SIVAL(*rdata,4,0x10);
323 SIVAL(*rdata,8,0x30);
324 SIVAL(*rdata,0xC,dword1);
325 SIVAL(*rdata,0x10,0x18);
329 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
330 int mdrcnt,int mprcnt,
331 char **rdata,char **rparam,
332 int *rdata_len,int *rparam_len)
338 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
342 LsarpcTNP1(data,rdata,rdata_len);
347 DEBUG(4,("\t- Suboperation %lx\n",id2));
351 LsarpcTNP2(data,rdata,rdata_len);
355 LsarpcTNP4(data,rdata,rdata_len);
359 LsarpcTNP3(data,rdata,rdata_len);
370 PAXX: Someone fix above.
371 The above API is indexing RPC calls based on RPC flags and
372 fragment length. I've decided to do it based on operation number :-)
375 /* this function is due to be replaced */
376 static void initrpcreply(char *inbuf, char *q)
380 SCVAL(q, 0, 5); q++; /* RPC version 5 */
381 SCVAL(q, 0, 0); q++; /* minor version 0 */
382 SCVAL(q, 0, 2); q++; /* RPC response packet */
383 SCVAL(q, 0, 3); q++; /* first frag + last frag */
384 RSIVAL(q, 0, 0x10000000); q += 4; /* packed data representation */
385 RSSVAL(q, 0, 0); q += 2; /* fragment length, fill in later */
386 SSVAL(q, 0, 0); q += 2; /* authentication length */
387 callid = RIVAL(inbuf, 12);
388 RSIVAL(q, 0, callid); q += 4; /* call identifier - match incoming RPC */
389 SIVAL(q, 0, 0x18); q += 4; /* allocation hint (no idea) */
390 SSVAL(q, 0, 0); q += 2; /* presentation context identifier */
391 SCVAL(q, 0, 0); q++; /* cancel count */
392 SCVAL(q, 0, 0); q++; /* reserved */
395 /* this function is due to be replaced */
396 static void endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen)
398 SSVAL(q, 8, datalen + 4);
399 SIVAL(q,0x10,datalen+4-0x18); /* allocation hint */
400 SIVAL(q, datalen, rtnval);
402 { int fd; fd = open("/tmp/rpc", O_RDWR); write(fd, q, datalen + 4); }
405 /* RID username mapping function. just for fun, it maps to the unix uid */
406 static uint32 name_to_rid(char *user_name)
408 struct passwd *pw = Get_Pwnam(user_name, False);
411 DEBUG(1,("Username %s is invalid on this system\n", user_name));
415 return (uint32)(pw->pw_uid);
419 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
420 char *dom_sid_to_string(DOM_SID *sid)
422 static pstring sidstr;
425 uint32 ia = (sid->id_auth[0]) +
426 (sid->id_auth[1] << 8 ) +
427 (sid->id_auth[2] << 16) +
428 (sid->id_auth[3] << 24);
430 sprintf(sidstr, "S-%d-%d", sid->sid_no, ia);
432 for (i = 0; i < sid->num_auths; i++)
434 sprintf(subauth, "-%d", sid->sub_auths[i]);
435 strcat(sidstr, subauth);
438 DEBUG(5,("dom_sid_to_string returning %s\n", sidstr));
442 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
443 /* identauth >= 2^32 can be detected because it will be specified in hex */
444 static void make_dom_sid(DOM_SID *sid, char *domsid)
449 DEBUG(4,("netlogon domain SID: %s\n", domsid));
451 /* assume, but should check, that domsid starts "S-" */
452 p = strtok(domsid+2,"-");
453 sid->sid_no = atoi(p);
455 /* identauth in decimal should be < 2^32 */
456 /* identauth in hex should be >= 2^32 */
457 identauth = atoi(strtok(0,"-"));
459 DEBUG(4,("netlogon rev %d\n", sid->sid_no));
460 DEBUG(4,("netlogon %s ia %d\n", p, identauth));
464 sid->id_auth[2] = (identauth & 0xff000000) >> 24;
465 sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
466 sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
467 sid->id_auth[5] = (identauth & 0x000000ff);
471 while ((p = strtok(0, "-")) != NULL)
473 sid->sub_auths[sid->num_auths++] = atoi(p);
477 static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len)
479 if (hdr == NULL) return;
481 hdr->major = 5; /* RPC version 5 */
482 hdr->minor = 0; /* minor version 0 */
483 hdr->pkt_type = 2; /* RPC response packet */
484 hdr->frag = 3; /* first frag + last frag */
485 hdr->pack_type = 1; /* packed data representation */
486 hdr->frag_len = data_len; /* fragment length, fill in later */
487 hdr->auth_len = 0; /* authentication length */
488 hdr->call_id = call_id; /* call identifier - match incoming RPC */
489 hdr->alloc_hint = data_len - 0x18; /* allocation hint (no idea) */
490 hdr->context_id = 0; /* presentation context identifier */
491 hdr->cancel_count = 0; /* cancel count */
492 hdr->reserved = 0; /* reserved */
495 static int make_rpc_reply(char *inbuf, char *q, int data_len)
497 uint32 callid = RIVAL(inbuf, 12);
500 create_rpc_reply(&hdr, callid, data_len);
501 return smb_io_rpc_hdr(False, &hdr, q, q, 4, 0) - q;
504 static int lsa_reply_open_policy(char *q, char *base)
509 /* set up the LSA QUERY INFO response */
510 /* bzero(&(r_o.pol.data), POL_HND_SIZE); */
511 for (i = 0; i < POL_HND_SIZE; i++)
517 /* store the response in the SMB stream */
518 q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0);
520 /* return length of SMB data stored */
521 return PTR_DIFF(q, base);
524 static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate)
526 hdr->uni_max_len = max_len;
527 hdr->uni_str_len = len;
528 hdr->undoc = terminate;
531 static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate)
533 make_uni_hdr(&(hdr->unihdr), max_len, len, terminate);
534 hdr->undoc_buffer = len > 0 ? 1 : 0;
537 static void make_unistr(UNISTR *str, char *buf)
539 /* store the string (null-terminated copy) */
540 PutUniCode((char *)(str->buffer), buf);
543 static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate)
545 /* set up string lengths. add one if string is not null-terminated */
546 str->uni_max_len = len + (terminate != 0 ? 1 : 0);
548 str->uni_str_len = len;
550 /* store the string (null-terminated copy) */
551 PutUniCode((char *)str->buffer, buf);
553 /* overwrite the last character: some strings are terminated with 4 not 0 */
554 str->buffer[len] = (uint16)terminate;
557 static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid)
565 static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str)
567 int len_sid_str = strlen(sid_str);
571 make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0);
572 make_unistr (&(sid2->str), sid_str);
575 static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid)
577 int domlen = strlen(dom_name);
579 d_q->uni_dom_max_len = domlen * 2;
581 d_q->uni_dom_str_len = domlen * 2;
583 d_q->buffer_dom_name = 0; /* domain buffer pointer */
584 d_q->buffer_dom_sid = 0; /* domain sid pointer */
586 /* NOT null-terminated: 4-terminated instead! */
587 make_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4);
589 make_dom_sid(&(d_q->dom_sid), dom_sid);
592 static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base,
593 char *dom_name, char *dom_sid)
595 LSA_R_QUERY_INFO r_q;
597 /* set up the LSA QUERY INFO response */
599 r_q.undoc_buffer = 1; /* not null */
600 r_q.info_class = q_q->info_class;
602 make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
606 /* store the response in the SMB stream */
607 q = lsa_io_r_query(False, &r_q, q, base, 4, 0);
609 /* return length of SMB data stored */
610 return PTR_DIFF(q, base);
613 /* pretty much hard-coded choice of "other" sids, unfortunately... */
614 static void make_dom_ref(DOM_R_REF *ref,
615 char *dom_name, char *dom_sid,
616 char *other_sid1, char *other_sid2, char *other_sid3)
618 int len_dom_name = strlen(dom_name);
619 int len_other_sid1 = strlen(other_sid1);
620 int len_other_sid2 = strlen(other_sid2);
621 int len_other_sid3 = strlen(other_sid3);
623 ref->undoc_buffer = 1;
624 ref->num_ref_doms_1 = 4;
625 ref->buffer_dom_name = 1;
626 ref->max_entries = 32;
627 ref->num_ref_doms_2 = 4;
629 make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0);
630 make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0);
631 make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0);
632 make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0);
634 if (dom_name != NULL)
636 make_unistr(&(ref->uni_dom_name), dom_name);
639 make_dom_sid(&(ref->ref_dom[0]), dom_sid );
640 make_dom_sid(&(ref->ref_dom[1]), other_sid1);
641 make_dom_sid(&(ref->ref_dom[2]), other_sid2);
642 make_dom_sid(&(ref->ref_dom[3]), other_sid3);
645 static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l,
646 int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
647 char *dom_name, char *dom_sid,
648 char *other_sid1, char *other_sid2, char *other_sid3)
652 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
653 other_sid1, other_sid2, other_sid3);
655 r_l->num_entries = num_entries;
656 r_l->undoc_buffer = 1;
657 r_l->num_entries2 = num_entries;
659 for (i = 0; i < num_entries; i++)
661 make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]);
664 r_l->num_entries3 = num_entries;
667 static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
668 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
669 char *dom_name, char *dom_sid,
670 char *other_sid1, char *other_sid2, char *other_sid3)
674 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
675 other_sid1, other_sid2, other_sid3);
677 r_l->num_entries = num_entries;
678 r_l->undoc_buffer = 1;
679 r_l->num_entries2 = num_entries;
681 for (i = 0; i < num_entries; i++)
683 make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]);
686 r_l->num_entries3 = num_entries;
689 static int lsa_reply_lookup_sids(char *q, char *base,
690 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
691 char *dom_name, char *dom_sid,
692 char *other_sid1, char *other_sid2, char *other_sid3)
694 LSA_R_LOOKUP_SIDS r_l;
696 /* set up the LSA Lookup SIDs response */
697 make_reply_lookup_sids(&r_l, num_entries, dom_sids,
698 dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
701 /* store the response in the SMB stream */
702 q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4, 0);
704 /* return length of SMB data stored */
705 return PTR_DIFF(q, base);
708 static int lsa_reply_lookup_rids(char *q, char *base,
709 int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
710 char *dom_name, char *dom_sid,
711 char *other_sid1, char *other_sid2, char *other_sid3)
713 LSA_R_LOOKUP_RIDS r_l;
715 /* set up the LSA Lookup RIDs response */
716 make_reply_lookup_rids(&r_l, num_entries, dom_rids,
717 dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
720 /* store the response in the SMB stream */
721 q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0);
723 /* return length of SMB data stored */
724 return PTR_DIFF(q, base);
727 static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c,
728 DOM_CHAL *srv_chal, int status)
730 DEBUG(6,("make_lsa_r_req_chal: %d\n", __LINE__));
731 memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
732 r_c->status = status;
735 static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
740 DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__));
742 /* set up the LSA REQUEST CHALLENGE response */
743 make_lsa_r_req_chal(&r_c, srv_chal, 0);
745 /* store the response in the SMB stream */
746 q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0);
748 DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__));
750 /* return length of SMB data stored */
751 return PTR_DIFF(q, base);
754 static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
755 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
757 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
758 memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
759 r_a->status = status;
762 static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
763 DOM_CHAL *resp_cred, int status)
767 /* set up the LSA AUTH 2 response */
769 make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
771 /* store the response in the SMB stream */
772 q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0);
774 /* return length of SMB data stored */
775 return PTR_DIFF(q, base);
778 static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a,
779 DOM_CRED *srv_cred, int status)
781 memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred));
782 r_a->status = status;
785 static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
786 DOM_CRED *srv_cred, int status)
790 /* set up the LSA Server Password Set response */
791 make_lsa_r_srv_pwset(&r_s, srv_cred, status);
793 /* store the response in the SMB stream */
794 q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0);
796 /* return length of SMB data stored */
797 return PTR_DIFF(q, base);
800 static void make_lsa_user_info(LSA_USER_INFO *usr,
804 NTTIME *kickoff_time,
805 NTTIME *pass_last_set_time,
806 NTTIME *pass_can_change_time,
807 NTTIME *pass_must_change_time,
831 char *other_sids) /* space-delimited set of SIDs */
833 /* only cope with one "other" sid, right now. */
834 /* need to count the number of space-delimited sids */
836 int num_other_sids = other_sids != NULL ? 1 : 0;
838 int len_user_name = strlen(user_name );
839 int len_full_name = strlen(full_name );
840 int len_logon_script = strlen(logon_script);
841 int len_profile_path = strlen(profile_path);
842 int len_home_dir = strlen(home_dir );
843 int len_dir_drive = strlen(dir_drive );
845 int len_logon_srv = strlen(logon_srv);
846 int len_logon_dom = strlen(logon_dom);
848 usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */
850 usr->logon_time = *logon_time;
851 usr->logoff_time = *logoff_time;
852 usr->kickoff_time = *kickoff_time;
853 usr->pass_last_set_time = *pass_last_set_time;
854 usr->pass_can_change_time = *pass_can_change_time;
855 usr->pass_must_change_time = *pass_must_change_time;
857 make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4);
858 make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4);
859 make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
860 make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
861 make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4);
862 make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4);
864 usr->logon_count = logon_count;
865 usr->bad_pw_count = bad_pw_count;
867 usr->user_id = user_id;
868 usr->group_id = group_id;
869 usr->num_groups = num_groups;
870 usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */
871 usr->user_flgs = user_flgs;
873 if (sess_key != NULL)
875 memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key));
879 bzero(usr->sess_key, sizeof(usr->sess_key));
882 make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
883 make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
885 usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
887 bzero(usr->padding, sizeof(usr->padding));
889 usr->num_other_sids = num_other_sids;
890 usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
892 make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0);
893 make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0);
894 make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0);
895 make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0);
896 make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0);
897 make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0);
899 usr->num_groups2 = num_groups;
900 for (i = 0; i < num_groups; i++)
902 usr->gids[i] = gids[i];
905 make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0);
906 make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0);
908 make_dom_sid(&(usr->dom_sid), dom_sid);
909 make_dom_sid(&(usr->other_sids[0]), other_sids);
913 static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
914 DOM_CRED *srv_cred, LSA_USER_INFO *user_info)
918 /* XXXX maybe we want to say 'no', reject the client's credentials */
919 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
920 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
922 /* store the user information, if there is any. */
923 r_s.user = user_info;
924 r_s.buffer_user = user_info != NULL ? 1 : 0;
925 r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER);
927 /* store the response in the SMB stream */
928 q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0);
930 /* return length of SMB data stored */
931 return PTR_DIFF(q, base);
935 static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
939 LSA_R_SAM_LOGOFF r_s;
941 /* XXXX maybe we want to say 'no', reject the client's credentials */
942 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
943 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
947 /* store the response in the SMB stream */
948 q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0);
950 /* return length of SMB data stored */
951 return PTR_DIFF(q, base);
955 static void api_lsa_open_policy( char *param, char *data,
956 char **rdata, int *rdata_len )
958 /* we might actually want to decode the query, but it's not necessary */
959 /* lsa_io_q_open_policy(...); */
961 /* return a 20 byte policy handle */
962 *rdata_len = lsa_reply_open_policy(*rdata + 0x18, *rdata);
965 static void api_lsa_query_info( char *param, char *data,
966 char **rdata, int *rdata_len )
968 LSA_Q_QUERY_INFO q_i;
972 /* grab the info class and policy handle */
973 lsa_io_q_query(True, &q_i, data + 0x18, data, 4, 0);
975 pstrcpy(dom_name, lp_workgroup());
976 pstrcpy(dom_sid , lp_domainsid());
978 /* construct reply. return status is always 0x0 */
979 *rdata_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata,
983 static void api_lsa_lookup_sids( char *param, char *data,
984 char **rdata, int *rdata_len )
987 LSA_Q_LOOKUP_SIDS q_l;
990 fstring dom_sids[MAX_LOOKUP_SIDS];
992 /* grab the info class and policy handle */
993 lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data, 4, 0);
995 pstrcpy(dom_name, lp_workgroup());
996 pstrcpy(dom_sid , lp_domainsid());
998 /* convert received SIDs to strings, so we can do them. */
999 for (i = 0; i < q_l.num_entries; i++)
1001 fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i])));
1004 /* construct reply. return status is always 0x0 */
1005 *rdata_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata,
1006 q_l.num_entries, dom_sids, /* text-converted SIDs */
1007 dom_name, dom_sid, /* domain name, domain SID */
1008 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1011 static void api_lsa_lookup_names( char *param, char *data,
1012 char **rdata, int *rdata_len )
1015 LSA_Q_LOOKUP_RIDS q_l;
1018 uint32 dom_rids[MAX_LOOKUP_SIDS];
1020 /* grab the info class and policy handle */
1021 lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data, 4, 0);
1023 pstrcpy(dom_name, lp_workgroup());
1024 pstrcpy(dom_sid , lp_domainsid());
1026 /* convert received RIDs to strings, so we can do them. */
1027 for (i = 0; i < q_l.num_entries; i++)
1029 char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
1030 dom_rids[i] = name_to_rid(user_name);
1033 /* construct reply. return status is always 0x0 */
1034 *rdata_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata,
1035 q_l.num_entries, dom_rids, /* text-converted SIDs */
1036 dom_name, dom_sid, /* domain name, domain SID */
1037 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1040 BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
1041 int mdrcnt,int mprcnt,
1042 char **rdata,char **rparam,
1043 int *rdata_len,int *rparam_len)
1045 uint16 opnum = SVAL(data,22);
1047 int pkttype = CVAL(data, 2);
1048 if (pkttype == 0x0b) /* RPC BIND */
1050 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1051 LsarpcTNP1(data,rdata,rdata_len);
1055 DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum));
1058 case LSA_OPENPOLICY:
1060 DEBUG(3,("LSA_OPENPOLICY\n"));
1061 api_lsa_open_policy(param, data, rdata, rdata_len);
1062 make_rpc_reply(data, *rdata, *rdata_len);
1066 case LSA_QUERYINFOPOLICY:
1068 DEBUG(3,("LSA_QUERYINFOPOLICY\n"));
1070 api_lsa_query_info(param, data, rdata, rdata_len);
1071 make_rpc_reply(data, *rdata, *rdata_len);
1075 case LSA_ENUMTRUSTDOM:
1077 char *q = *rdata + 0x18;
1079 DEBUG(3,("LSA_ENUMTRUSTDOM\n"));
1081 initrpcreply(data, *rdata);
1083 SIVAL(q, 0, 0); /* enumeration context */
1084 SIVAL(q, 0, 4); /* entries read */
1085 SIVAL(q, 0, 8); /* trust information */
1087 endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len);
1094 char *q = *rdata + 0x18;
1096 DEBUG(3,("LSA_CLOSE\n"));
1098 initrpcreply(data, *rdata);
1106 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1111 case LSA_OPENSECRET:
1113 char *q = *rdata + 0x18;
1114 DEBUG(3,("LSA_OPENSECRET\n"));
1116 initrpcreply(data, *rdata);
1124 endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len);
1129 case LSA_LOOKUPSIDS:
1131 DEBUG(3,("LSA_OPENSECRET\n"));
1132 api_lsa_lookup_sids(param, data, rdata, rdata_len);
1133 make_rpc_reply(data, *rdata, *rdata_len);
1137 case LSA_LOOKUPNAMES:
1139 DEBUG(3,("LSA_LOOKUPNAMES\n"));
1140 api_lsa_lookup_names(param, data, rdata, rdata_len);
1141 make_rpc_reply(data, *rdata, *rdata_len);
1147 DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum));
1154 static BOOL update_dcinfo(int cnum, uint16 vuid,
1155 struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct)
1157 struct smb_passwd *smb_pass;
1161 smb_pass = get_smbpwnam(mach_acct);
1162 become_user(cnum, vuid);
1164 if (smb_pass != NULL)
1166 memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw));
1167 DEBUG(5,("dc->md4pw(%d) :", sizeof(dc->md4pw)));
1168 dump_data(5, dc->md4pw, 16);
1172 /* No such machine account. Should error out here, but we'll
1173 print and carry on */
1174 DEBUG(1,("No account in domain for %s\n", mach_acct));
1180 for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]);
1181 DEBUG(4,("pass %s %s\n", mach_acct, foo));
1184 /* copy the client credentials */
1185 memcpy(dc->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
1186 memcpy(dc->clnt_cred.data, clnt_chal->data, sizeof(clnt_chal->data));
1188 /* create a server challenge for the client */
1189 /* PAXX: set these to random values. */
1190 /* lkcl: paul, you mentioned that it doesn't really matter much */
1191 for (i = 0; i < 8; i++)
1193 dc->srv_chal.data[i] = 0xA5;
1196 /* from client / server challenges and md4 password, generate sess key */
1197 cred_session_key(&(dc->clnt_chal), &(dc->srv_chal),
1198 dc->md4pw, dc->sess_key);
1200 DEBUG(6,("update_dcinfo: %d\n", __LINE__));
1205 static void api_lsa_req_chal( int cnum, uint16 vuid,
1207 char *param, char *data,
1208 char **rdata, int *rdata_len )
1214 /* grab the challenge... */
1215 lsa_io_q_req_chal(True, &q_r, data + 0x18, data, 4, 0);
1217 fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer));
1219 strcat(mach_acct, "$");
1221 DEBUG(6,("q_r.clnt_chal.data(%d) :", sizeof(q_r.clnt_chal.data)));
1222 dump_data(6, q_r.clnt_chal.data, 8);
1224 update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct);
1226 /* construct reply. return status is always 0x0 */
1227 *rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata,
1228 &(vuser->dc.srv_chal));
1232 static void api_lsa_auth_2( user_struct *vuser,
1233 char *param, char *data,
1234 char **rdata, int *rdata_len )
1243 /* grab the challenge... */
1244 lsa_io_q_auth_2(True, &q_a, data + 0x18, data, 4, 0);
1246 /* check that the client credentials are valid */
1247 cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
1248 &(vuser->dc.srv_cred), srv_time);
1250 /* create server credentials for inclusion in the reply */
1251 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), srv_time, &srv_chal);
1253 /* construct reply. */
1254 *rdata_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata,
1259 static BOOL deal_with_credentials(user_struct *vuser,
1260 DOM_CRED *clnt_cred, DOM_CRED *srv_cred)
1262 UTIME new_clnt_time;
1264 /* doesn't matter that server time is 0 */
1265 srv_cred->timestamp.time = 0;
1267 /* check that the client credentials are valid */
1268 if (cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key,
1269 &(vuser->dc.srv_cred), clnt_cred->timestamp))
1274 /* increment client time by one second */
1275 new_clnt_time.time = clnt_cred->timestamp.time + 1;
1277 /* create server credentials for inclusion in the reply */
1278 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time,
1279 &(srv_cred->challenge));
1281 /* update the client and server credentials, for use next time... */
1282 *(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time );
1287 static void api_lsa_srv_pwset( user_struct *vuser,
1288 char *param, char *data,
1289 char **rdata, int *rdata_len )
1291 LSA_Q_SRV_PWSET q_a;
1295 /* grab the challenge and encrypted password ... */
1296 lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data, 4, 0);
1298 /* checks and updates credentials. creates reply credentials */
1299 deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred);
1301 /* construct reply. always indicate failure. nt keeps going... */
1302 *rdata_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata,
1304 NT_STATUS_WRONG_PASSWORD|0xC000000);
1308 static void api_lsa_sam_logoff( user_struct *vuser,
1309 char *param, char *data,
1310 char **rdata, int *rdata_len )
1312 LSA_Q_SAM_LOGOFF q_l;
1316 /* grab the challenge... */
1317 lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data, 4, 0);
1319 /* checks and updates credentials. creates reply credentials */
1320 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred);
1322 /* construct reply. always indicate success */
1323 *rdata_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata,
1329 static void api_lsa_sam_logon( user_struct *vuser,
1330 char *param, char *data,
1331 char **rdata, int *rdata_len )
1333 LSA_Q_SAM_LOGON q_l;
1334 LSA_USER_INFO usr_info;
1335 LSA_USER_INFO *p_usr_info = NULL;
1339 lsa_io_q_sam_logon(True, &q_l, data + 0x18, data, 4, 0);
1341 /* checks and updates credentials. creates reply credentials */
1342 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds);
1347 pstring logon_script;
1348 pstring profile_path;
1352 pstring my_workgroup;
1355 extern pstring myname;
1357 dummy_time.low = 0xffffffff;
1358 dummy_time.high = 0x7fffffff;
1360 get_myname(myname, NULL);
1362 pstrcpy(logon_script, lp_logon_script());
1363 pstrcpy(profile_path, lp_logon_path ());
1364 pstrcpy(dom_sid , lp_domainsid ());
1365 pstrcpy(my_workgroup, lp_workgroup ());
1367 pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer));
1368 pstrcpy(my_name , myname );
1371 pstrcpy(home_drive , "a:" );
1373 #if (defined(NETGROUP) && defined(AUTOMOUNT))
1374 pstrcpy(home_dir , vuser->home_share);
1376 pstrcpy(home_dir , "\\\\%L\\%U");
1377 standard_sub_basic(home_dir);
1380 p_usr_info = &usr_info;
1382 make_lsa_user_info(p_usr_info,
1384 &dummy_time, /* logon_time */
1385 &dummy_time, /* logoff_time */
1386 &dummy_time, /* kickoff_time */
1387 &dummy_time, /* pass_last_set_time */
1388 &dummy_time, /* pass_can_change_time */
1389 &dummy_time, /* pass_must_change_time */
1391 username, /* user_name */
1392 vuser->real_name, /* full_name */
1393 logon_script, /* logon_script */
1394 profile_path, /* profile_path */
1395 home_dir, /* home_dir */
1396 home_drive, /* dir_drive */
1398 0, /* logon_count */
1399 0, /* bad_pw_count */
1401 vuser->uid, /* uint32 user_id */
1402 vuser->gid, /* uint32 group_id */
1403 0, /* uint32 num_groups */
1404 NULL, /* DOM_GID *gids */
1405 0x20, /* uint32 user_flgs */
1407 NULL, /* char sess_key[16] */
1409 my_name, /* char *logon_srv */
1410 my_workgroup, /* char *logon_dom */
1412 dom_sid, /* char *dom_sid */
1413 NULL); /* char *other_sids */
1416 *rdata_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata,
1417 &srv_creds, p_usr_info);
1421 BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
1422 int mdrcnt,int mprcnt,
1423 char **rdata,char **rparam,
1424 int *rdata_len,int *rparam_len)
1426 uint16 opnum = SVAL(data,22);
1427 int pkttype = CVAL(data, 2);
1431 if (pkttype == 0x0b) /* RPC BIND */
1433 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1434 LsarpcTNP1(data,rdata,rdata_len);
1438 DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum));
1440 if ((vuser = get_valid_user_struct(uid)) == NULL) return False;
1442 DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
1443 #if defined(NETGROUP) && defined(AUTOMOUNT)
1444 DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
1451 DEBUG(3,("LSA_REQCHAL\n"));
1452 api_lsa_req_chal(cnum, uid, vuser, param, data, rdata, rdata_len);
1453 make_rpc_reply(data, *rdata, *rdata_len);
1459 DEBUG(3,("LSA_AUTH2\n"));
1460 api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
1461 make_rpc_reply(data, *rdata, *rdata_len);
1467 DEBUG(3,("LSA_SRVPWSET\n"));
1468 api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
1469 make_rpc_reply(data, *rdata, *rdata_len);
1475 DEBUG(3,("LSA_SAMLOGON\n"));
1476 api_lsa_sam_logon(vuser, param, data, rdata, rdata_len);
1477 make_rpc_reply(data, *rdata, *rdata_len);
1483 DEBUG(3,("LSA_SAMLOGOFF\n"));
1484 api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len);
1490 DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
1498 #endif /* NTDOMAIN */