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 [] =
64 /****************************************************************************
65 reply to an open and X on a named pipe
67 In fact what we do is to open a regular file with the same name in
68 /tmp. This can then be closed as normal. Reading and writing won't
69 make much sense, but will do *something*. The real reason for this
70 support is to be able to do transactions on them (well, on lsarpc
71 for domain login purposes...).
73 This code is basically stolen from reply_open_and_X with some
74 wrinkles to handle pipes.
75 ****************************************************************************/
76 int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
79 int cnum = SVAL(inbuf,smb_tid);
81 int smb_mode = SVAL(inbuf,smb_vwv3);
82 int smb_attr = SVAL(inbuf,smb_vwv5);
84 int open_flags = SVAL(inbuf,smb_vwv2);
85 int smb_sattr = SVAL(inbuf,smb_vwv4);
86 uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
88 int smb_ofun = SVAL(inbuf,smb_vwv8);
90 int size=0,fmode=0,mtime=0,rmode=0;
94 BOOL bad_path = False;
96 /* XXXX we need to handle passed times, sattr and flags */
97 pstrcpy(fname,smb_buf(inbuf));
99 /* If the name doesn't start \PIPE\ then this is directed */
100 /* at a mailslot or something we really, really don't understand, */
101 /* not just something we really don't understand. */
102 if ( strncmp(fname,PIPE,PIPELEN) != 0 )
103 return(ERROR(ERRSRV,ERRaccess));
105 DEBUG(4,("Opening pipe %s.\n", fname));
107 /* Strip \PIPE\ off the name. */
108 pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
110 /* See if it is one we want to handle. */
111 for( i = 0; known_pipes[i] ; i++ )
112 if( strcmp(fname,known_pipes[i]) == 0 )
115 if ( known_pipes[i] == NULL )
116 return(ERROR(ERRSRV,ERRaccess));
118 /* Known pipes arrive with DIR attribs. Remove it so a regular file */
119 /* can be opened and add it in after the open. */
120 DEBUG(3,("Known pipe %s opening.\n",fname));
122 Connections[cnum].read_only = 0;
123 smb_ofun |= 0x10; /* Add Create it not exists flag */
125 unix_convert(fname,cnum,0,&bad_path);
127 fnum = find_free_file();
129 return(ERROR(ERRSRV,ERRnofids));
131 if (!check_name(fname,cnum))
132 return(UNIXERROR(ERRDOS,ERRnoaccess));
134 unixmode = unix_mode(cnum,smb_attr);
136 open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
137 0, &rmode,&smb_action);
139 if (!Files[fnum].open)
141 /* Change the error code if bad_path was set. */
142 if((errno == ENOENT) && bad_path)
144 unix_ERR_class = ERRDOS;
145 unix_ERR_code = ERRbadpath;
147 return(UNIXERROR(ERRDOS,ERRnoaccess));
150 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
152 return(ERROR(ERRDOS,ERRnoaccess));
156 fmode = dos_mode(cnum,fname,&sbuf);
157 mtime = sbuf.st_mtime;
160 return(ERROR(ERRDOS,ERRnoaccess));
163 /* Prepare the reply */
164 set_message(outbuf,15,0,True);
166 /* Put things back the way they were. */
167 Connections[cnum].read_only = 1;
169 /* Mark the opened file as an existing named pipe in message mode. */
170 SSVAL(outbuf,smb_vwv9,2);
171 SSVAL(outbuf,smb_vwv10,0xc700);
174 DEBUG(4,("Resetting open result to open from create.\n"));
178 SSVAL(outbuf,smb_vwv2,fnum);
179 SSVAL(outbuf,smb_vwv3,fmode);
180 put_dos_date3(outbuf,smb_vwv4,mtime);
181 SIVAL(outbuf,smb_vwv6,size);
182 SSVAL(outbuf,smb_vwv8,rmode);
183 SSVAL(outbuf,smb_vwv11,smb_action);
187 DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
188 fname, fnum, Files[fnum].name));
190 return chain_reply(inbuf,outbuf,length,bufsize);
194 /****************************************************************************
197 SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
198 so just blithely return True. This is really only for NT domain stuff,
199 we we're only handling that - don't assume Samba now does complete
201 ****************************************************************************/
202 BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
203 int mdrcnt,int mprcnt,
204 char **rdata,char **rparam,
205 int *rdata_len,int *rparam_len)
209 id = param[0] + (param[1] << 8);
210 DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
215 /****************************************************************************
218 TransactNamedPipe on \PIPE\lsarpc.
219 ****************************************************************************/
220 static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
222 uint32 dword1, dword2;
223 char pname[] = "\\PIPE\\lsass";
225 /* All kinds of mysterious numbers here */
227 *rdata = REALLOC(*rdata,*rdata_len);
229 dword1 = IVAL(data,0xC);
230 dword2 = IVAL(data,0x10);
232 SIVAL(*rdata,0,0xc0005);
233 SIVAL(*rdata,4,0x10);
234 SIVAL(*rdata,8,0x44);
235 SIVAL(*rdata,0xC,dword1);
237 SIVAL(*rdata,0x10,dword2);
238 SIVAL(*rdata,0x14,0x15);
239 SSVAL(*rdata,0x18,sizeof(pname));
240 strcpy(*rdata + 0x1a,pname);
241 SIVAL(*rdata,0x28,1);
242 memcpy(*rdata + 0x30, data + 0x34, 0x14);
245 static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
249 /* All kinds of mysterious numbers here */
251 *rdata = REALLOC(*rdata,*rdata_len);
253 dword1 = IVAL(data,0xC);
255 SIVAL(*rdata,0,0x03020005);
256 SIVAL(*rdata,4,0x10);
257 SIVAL(*rdata,8,0x30);
258 SIVAL(*rdata,0xC,dword1);
259 SIVAL(*rdata,0x10,0x18);
260 SIVAL(*rdata,0x1c,0x44332211);
261 SIVAL(*rdata,0x20,0x88776655);
262 SIVAL(*rdata,0x24,0xCCBBAA99);
263 SIVAL(*rdata,0x28,0x11FFEEDD);
266 static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
270 char * workgroup = myworkgroup;
271 int wglen = strlen(workgroup);
274 /* All kinds of mysterious numbers here */
275 *rdata_len = 90 + 2 * wglen;
276 *rdata = REALLOC(*rdata,*rdata_len);
278 dword1 = IVAL(data,0xC);
279 word1 = SVAL(data,0x2C);
281 SIVAL(*rdata,0,0x03020005);
282 SIVAL(*rdata,4,0x10);
283 SIVAL(*rdata,8,0x60);
284 SIVAL(*rdata,0xC,dword1);
285 SIVAL(*rdata,0x10,0x48);
286 SSVAL(*rdata,0x18,0x5988); /* This changes */
287 SSVAL(*rdata,0x1A,0x15);
288 SSVAL(*rdata,0x1C,word1);
289 SSVAL(*rdata,0x20,6);
290 SSVAL(*rdata,0x22,8);
291 SSVAL(*rdata,0x24,0x8E8); /* So does this */
292 SSVAL(*rdata,0x26,0x15);
293 SSVAL(*rdata,0x28,0x4D48); /* And this */
294 SSVAL(*rdata,0x2A,0x15);
295 SIVAL(*rdata,0x2C,4);
296 SIVAL(*rdata,0x34,wglen);
297 for ( i = 0 ; i < wglen ; i++ )
298 (*rdata)[0x38 + i * 2] = workgroup[i];
300 /* Now fill in the rest */
301 i = 0x38 + wglen * 2;
302 SSVAL(*rdata,i,0x648);
304 SIVAL(*rdata,i+6,0x401);
305 SSVAL(*rdata,i+0xC,0x500);
306 SIVAL(*rdata,i+0xE,0x15);
307 SIVAL(*rdata,i+0x12,0x2372FE1);
308 SIVAL(*rdata,i+0x16,0x7E831BEF);
309 SIVAL(*rdata,i+0x1A,0x4B454B2);
312 static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
316 /* All kinds of mysterious numbers here */
318 *rdata = REALLOC(*rdata,*rdata_len);
320 dword1 = IVAL(data,0xC);
322 SIVAL(*rdata,0,0x03020005);
323 SIVAL(*rdata,4,0x10);
324 SIVAL(*rdata,8,0x30);
325 SIVAL(*rdata,0xC,dword1);
326 SIVAL(*rdata,0x10,0x18);
330 BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
331 int mdrcnt,int mprcnt,
332 char **rdata,char **rparam,
333 int *rdata_len,int *rparam_len)
339 DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
343 LsarpcTNP1(data,rdata,rdata_len);
348 DEBUG(4,("\t- Suboperation %lx\n",id2));
352 LsarpcTNP2(data,rdata,rdata_len);
356 LsarpcTNP4(data,rdata,rdata_len);
360 LsarpcTNP3(data,rdata,rdata_len);
371 PAXX: Someone fix above.
372 The above API is indexing RPC calls based on RPC flags and
373 fragment length. I've decided to do it based on operation number :-)
376 /* this function is due to be replaced */
377 static void initrpcreply(char *inbuf, char *q)
381 SCVAL(q, 0, 5); q++; /* RPC version 5 */
382 SCVAL(q, 0, 0); q++; /* minor version 0 */
383 SCVAL(q, 0, 2); q++; /* RPC response packet */
384 SCVAL(q, 0, 3); q++; /* first frag + last frag */
385 RSIVAL(q, 0, 0x10000000); q += 4; /* packed data representation */
386 RSSVAL(q, 0, 0); q += 2; /* fragment length, fill in later */
387 SSVAL(q, 0, 0); q += 2; /* authentication length */
388 callid = RIVAL(inbuf, 12);
389 RSIVAL(q, 0, callid); q += 4; /* call identifier - match incoming RPC */
390 SIVAL(q, 0, 0x18); q += 4; /* allocation hint (no idea) */
391 SSVAL(q, 0, 0); q += 2; /* presentation context identifier */
392 SCVAL(q, 0, 0); q++; /* cancel count */
393 SCVAL(q, 0, 0); q++; /* reserved */
396 /* this function is due to be replaced */
397 static void endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen)
399 SSVAL(q, 8, datalen + 4);
400 SIVAL(q,0x10,datalen+4-0x18); /* allocation hint */
401 SIVAL(q, datalen, rtnval);
403 { int fd; fd = open("/tmp/rpc", O_RDWR); write(fd, q, datalen + 4); }
406 /* RID username mapping function. just for fun, it maps to the unix uid */
407 static uint32 name_to_rid(char *user_name)
409 struct passwd *pw = Get_Pwnam(user_name, False);
412 DEBUG(1,("Username %s is invalid on this system\n", user_name));
416 return (uint32)(pw->pw_uid);
420 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
421 char *dom_sid_to_string(DOM_SID *sid)
423 static pstring sidstr;
426 uint32 ia = (sid->id_auth[0]) +
427 (sid->id_auth[1] << 8 ) +
428 (sid->id_auth[2] << 16) +
429 (sid->id_auth[3] << 24);
431 sprintf(sidstr, "S-%d-%d", sid->sid_no, ia);
433 for (i = 0; i < sid->num_auths; i++)
435 sprintf(subauth, "-%d", sid->sub_auths[i]);
436 strcat(sidstr, subauth);
439 DEBUG(5,("dom_sid_to_string returning %s\n", sidstr));
443 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
444 /* identauth >= 2^32 can be detected because it will be specified in hex */
445 static void make_dom_sid(DOM_SID *sid, char *domsid)
450 DEBUG(4,("netlogon domain SID: %s\n", domsid));
452 /* assume, but should check, that domsid starts "S-" */
453 p = strtok(domsid+2,"-");
454 sid->sid_no = atoi(p);
456 /* identauth in decimal should be < 2^32 */
457 /* identauth in hex should be >= 2^32 */
458 identauth = atoi(strtok(0,"-"));
460 DEBUG(4,("netlogon rev %d\n", sid->sid_no));
461 DEBUG(4,("netlogon %s ia %d\n", p, identauth));
465 sid->id_auth[2] = (identauth & 0xff000000) >> 24;
466 sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
467 sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
468 sid->id_auth[5] = (identauth & 0x000000ff);
472 while ((p = strtok(0, "-")) != NULL)
474 sid->sub_auths[sid->num_auths++] = atoi(p);
478 static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len)
480 if (hdr == NULL) return;
482 hdr->major = 5; /* RPC version 5 */
483 hdr->minor = 0; /* minor version 0 */
484 hdr->pkt_type = 2; /* RPC response packet */
485 hdr->frag = 3; /* first frag + last frag */
486 hdr->pack_type = 0x10; /* packed data representation */
487 hdr->frag_len = data_len; /* fragment length, fill in later */
488 hdr->auth_len = 0; /* authentication length */
489 hdr->call_id = call_id; /* call identifier - match incoming RPC */
490 hdr->alloc_hint = data_len - 0x18; /* allocation hint (no idea) */
491 hdr->context_id = 0; /* presentation context identifier */
492 hdr->cancel_count = 0; /* cancel count */
493 hdr->reserved = 0; /* reserved */
496 static int make_rpc_reply(char *inbuf, char *q, int data_len)
498 uint32 callid = IVAL(inbuf, 12);
501 DEBUG(5,("make_rpc_reply. callid: %x\n", callid));
503 create_rpc_reply(&hdr, callid, data_len);
504 return PTR_DIFF(smb_io_rpc_hdr(False, &hdr, q, q, 4), q);
507 static int lsa_reply_open_policy(char *q, char *base)
512 static char handle[20] =
513 { 0x00, 0x00, 0x00, 0x00,
514 0x2f, 0x79, 0x0a, 0x81,
515 0xd5, 0x17, 0xd1, 0x11,
516 0x80, 0xaf, 0x96, 0xcd,
517 0x50, 0xf8, 0xbc, 0x6c
519 /* set up the LSA QUERY INFO response */
520 /* bzero(&(r_o.pol.data), POL_HND_SIZE); */
521 for (i = 0; i < POL_HND_SIZE; i++)
523 r_o.pol.data[i] = handle[i];
527 /* store the response in the SMB stream */
528 q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0);
530 /* return length of SMB data stored */
531 return PTR_DIFF(q, base);
534 static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate)
536 hdr->uni_max_len = max_len;
537 hdr->uni_str_len = len;
538 hdr->undoc = terminate;
541 static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate)
543 make_uni_hdr(&(hdr->unihdr), max_len, len, terminate);
544 hdr->undoc_buffer = len > 0 ? 1 : 0;
547 static void make_unistr(UNISTR *str, char *buf)
549 /* store the string (null-terminated copy) */
550 PutUniCode((char *)(str->buffer), buf);
553 static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate)
555 /* set up string lengths. add one if string is not null-terminated */
556 str->uni_max_len = len + (terminate != 0 ? 1 : 0);
558 str->uni_str_len = len;
560 /* store the string (null-terminated copy) */
561 PutUniCode((char *)str->buffer, buf);
563 /* overwrite the last character: some strings are terminated with 4 not 0 */
564 str->buffer[len] = (uint16)terminate;
567 static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid)
575 static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str)
577 int len_sid_str = strlen(sid_str);
581 make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0);
582 make_unistr (&(sid2->str), sid_str);
585 static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid)
587 int domlen = strlen(dom_name);
589 d_q->uni_dom_max_len = domlen * 2;
591 d_q->uni_dom_str_len = domlen * 2;
593 d_q->buffer_dom_name = 0; /* domain buffer pointer */
594 d_q->buffer_dom_sid = 0; /* domain sid pointer */
596 /* NOT null-terminated: 4-terminated instead! */
597 make_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4);
599 make_dom_sid(&(d_q->dom_sid), dom_sid);
602 static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base,
603 char *dom_name, char *dom_sid)
605 LSA_R_QUERY_INFO r_q;
607 /* set up the LSA QUERY INFO response */
609 r_q.undoc_buffer = 1; /* not null */
610 r_q.info_class = q_q->info_class;
612 make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
616 /* store the response in the SMB stream */
617 q = lsa_io_r_query(False, &r_q, q, base, 4, 0);
619 /* return length of SMB data stored */
620 return PTR_DIFF(q, base);
623 /* pretty much hard-coded choice of "other" sids, unfortunately... */
624 static void make_dom_ref(DOM_R_REF *ref,
625 char *dom_name, char *dom_sid,
626 char *other_sid1, char *other_sid2, char *other_sid3)
628 int len_dom_name = strlen(dom_name);
629 int len_other_sid1 = strlen(other_sid1);
630 int len_other_sid2 = strlen(other_sid2);
631 int len_other_sid3 = strlen(other_sid3);
633 ref->undoc_buffer = 1;
634 ref->num_ref_doms_1 = 4;
635 ref->buffer_dom_name = 1;
636 ref->max_entries = 32;
637 ref->num_ref_doms_2 = 4;
639 make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0);
640 make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0);
641 make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0);
642 make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0);
644 if (dom_name != NULL)
646 make_unistr(&(ref->uni_dom_name), dom_name);
649 make_dom_sid(&(ref->ref_dom[0]), dom_sid );
650 make_dom_sid(&(ref->ref_dom[1]), other_sid1);
651 make_dom_sid(&(ref->ref_dom[2]), other_sid2);
652 make_dom_sid(&(ref->ref_dom[3]), other_sid3);
655 static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l,
656 int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
657 char *dom_name, char *dom_sid,
658 char *other_sid1, char *other_sid2, char *other_sid3)
662 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
663 other_sid1, other_sid2, other_sid3);
665 r_l->num_entries = num_entries;
666 r_l->undoc_buffer = 1;
667 r_l->num_entries2 = num_entries;
669 for (i = 0; i < num_entries; i++)
671 make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]);
674 r_l->num_entries3 = num_entries;
677 static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
678 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
679 char *dom_name, char *dom_sid,
680 char *other_sid1, char *other_sid2, char *other_sid3)
684 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
685 other_sid1, other_sid2, other_sid3);
687 r_l->num_entries = num_entries;
688 r_l->undoc_buffer = 1;
689 r_l->num_entries2 = num_entries;
691 for (i = 0; i < num_entries; i++)
693 make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]);
696 r_l->num_entries3 = num_entries;
699 static int lsa_reply_lookup_sids(char *q, char *base,
700 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
701 char *dom_name, char *dom_sid,
702 char *other_sid1, char *other_sid2, char *other_sid3)
704 LSA_R_LOOKUP_SIDS r_l;
706 /* set up the LSA Lookup SIDs response */
707 make_reply_lookup_sids(&r_l, num_entries, dom_sids,
708 dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
711 /* store the response in the SMB stream */
712 q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4, 0);
714 /* return length of SMB data stored */
715 return PTR_DIFF(q, base);
718 static int lsa_reply_lookup_rids(char *q, char *base,
719 int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
720 char *dom_name, char *dom_sid,
721 char *other_sid1, char *other_sid2, char *other_sid3)
723 LSA_R_LOOKUP_RIDS r_l;
725 /* set up the LSA Lookup RIDs response */
726 make_reply_lookup_rids(&r_l, num_entries, dom_rids,
727 dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
730 /* store the response in the SMB stream */
731 q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0);
733 /* return length of SMB data stored */
734 return PTR_DIFF(q, base);
737 static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c,
738 DOM_CHAL *srv_chal, int status)
740 memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(r_c->srv_chal.data));
741 r_c->status = status;
744 static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
749 /* set up the LSA REQUEST CHALLENGE response */
751 make_lsa_r_req_chal(&r_c, srv_chal, 0);
753 /* store the response in the SMB stream */
754 q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0);
756 /* return length of SMB data stored */
757 return PTR_DIFF(q, base);
760 static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
761 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
763 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
764 memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
765 r_a->status = status;
768 static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
769 DOM_CHAL *resp_cred, int status)
773 /* set up the LSA AUTH 2 response */
775 make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
777 /* store the response in the SMB stream */
778 q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0);
780 /* return length of SMB data stored */
781 return PTR_DIFF(q, base);
784 static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a,
785 DOM_CRED *srv_cred, int status)
787 memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred));
788 r_a->status = status;
791 static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
792 DOM_CRED *srv_cred, int status)
796 /* set up the LSA Server Password Set response */
797 make_lsa_r_srv_pwset(&r_s, srv_cred, status);
799 /* store the response in the SMB stream */
800 q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0);
802 /* return length of SMB data stored */
803 return PTR_DIFF(q, base);
806 static void make_lsa_user_info(LSA_USER_INFO *usr,
810 NTTIME *kickoff_time,
811 NTTIME *pass_last_set_time,
812 NTTIME *pass_can_change_time,
813 NTTIME *pass_must_change_time,
837 char *other_sids) /* space-delimited set of SIDs */
839 /* only cope with one "other" sid, right now. */
840 /* need to count the number of space-delimited sids */
842 int num_other_sids = other_sids != NULL ? 1 : 0;
844 int len_user_name = strlen(user_name );
845 int len_full_name = strlen(full_name );
846 int len_logon_script = strlen(logon_script);
847 int len_profile_path = strlen(profile_path);
848 int len_home_dir = strlen(home_dir );
849 int len_dir_drive = strlen(dir_drive );
851 int len_logon_srv = strlen(logon_srv);
852 int len_logon_dom = strlen(logon_dom);
854 usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */
856 usr->logon_time = *logon_time;
857 usr->logoff_time = *logoff_time;
858 usr->kickoff_time = *kickoff_time;
859 usr->pass_last_set_time = *pass_last_set_time;
860 usr->pass_can_change_time = *pass_can_change_time;
861 usr->pass_must_change_time = *pass_must_change_time;
863 make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4);
864 make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4);
865 make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
866 make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
867 make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4);
868 make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4);
870 usr->logon_count = logon_count;
871 usr->bad_pw_count = bad_pw_count;
873 usr->user_id = user_id;
874 usr->group_id = group_id;
875 usr->num_groups = num_groups;
876 usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */
877 usr->user_flgs = user_flgs;
879 if (sess_key != NULL)
881 memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key));
885 bzero(usr->sess_key, sizeof(usr->sess_key));
888 make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
889 make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
891 usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
893 bzero(usr->padding, sizeof(usr->padding));
895 usr->num_other_sids = num_other_sids;
896 usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
898 make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0);
899 make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0);
900 make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0);
901 make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0);
902 make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0);
903 make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0);
905 usr->num_groups2 = num_groups;
906 for (i = 0; i < num_groups; i++)
908 usr->gids[i] = gids[i];
911 make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0);
912 make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0);
914 make_dom_sid(&(usr->dom_sid), dom_sid);
915 make_dom_sid(&(usr->other_sids[0]), other_sids);
919 static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
920 DOM_CRED *srv_cred, LSA_USER_INFO *user_info)
924 /* XXXX maybe we want to say 'no', reject the client's credentials */
925 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
926 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
928 /* store the user information, if there is any. */
929 r_s.user = user_info;
930 r_s.buffer_user = user_info != NULL ? 1 : 0;
931 r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER);
933 /* store the response in the SMB stream */
934 q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0);
936 /* return length of SMB data stored */
937 return PTR_DIFF(q, base);
941 static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
945 LSA_R_SAM_LOGOFF r_s;
947 /* XXXX maybe we want to say 'no', reject the client's credentials */
948 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
949 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
953 /* store the response in the SMB stream */
954 q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0);
956 /* return length of SMB data stored */
957 return PTR_DIFF(q, base);
961 static void api_lsa_open_policy( char *param, char *data,
962 char **rdata, int *rdata_len )
964 /* we might actually want to decode the query, but it's not necessary */
965 /* lsa_io_q_open_policy(...); */
967 /* construct a 20 byte policy handle. return length*/
968 *rdata_len = lsa_reply_open_policy(*rdata + 0x18, *rdata);
971 static int api_lsa_query_info( char *param, char *data,
972 char **rdata, int *rdata_len )
974 LSA_Q_QUERY_INFO q_i;
978 /* grab the info class and policy handle */
979 lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4, 0);
981 pstrcpy(dom_name, lp_workgroup());
982 pstrcpy(dom_sid , lp_domainsid());
984 /* construct reply. return status is always 0x0 */
985 return lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata,
989 static void api_lsa_lookup_sids( char *param, char *data,
990 char **rdata, int *rdata_len )
993 LSA_Q_LOOKUP_SIDS q_l;
996 fstring dom_sids[MAX_LOOKUP_SIDS];
998 /* grab the info class and policy handle */
999 lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1001 pstrcpy(dom_name, lp_workgroup());
1002 pstrcpy(dom_sid , lp_domainsid());
1004 /* convert received SIDs to strings, so we can do them. */
1005 for (i = 0; i < q_l.num_entries; i++)
1007 fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i])));
1010 /* construct reply. return status is always 0x0 */
1011 *rdata_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata,
1012 q_l.num_entries, dom_sids, /* text-converted SIDs */
1013 dom_name, dom_sid, /* domain name, domain SID */
1014 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1017 static void api_lsa_lookup_names( char *param, char *data,
1018 char **rdata, int *rdata_len )
1021 LSA_Q_LOOKUP_RIDS q_l;
1024 uint32 dom_rids[MAX_LOOKUP_SIDS];
1026 /* grab the info class and policy handle */
1027 lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1029 pstrcpy(dom_name, lp_workgroup());
1030 pstrcpy(dom_sid , lp_domainsid());
1032 /* convert received RIDs to strings, so we can do them. */
1033 for (i = 0; i < q_l.num_entries; i++)
1035 char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
1036 dom_rids[i] = name_to_rid(user_name);
1039 /* construct reply. return status is always 0x0 */
1040 *rdata_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata,
1041 q_l.num_entries, dom_rids, /* text-converted SIDs */
1042 dom_name, dom_sid, /* domain name, domain SID */
1043 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1046 BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
1047 int mdrcnt,int mprcnt,
1048 char **rdata,char **rparam,
1049 int *rdata_len,int *rparam_len)
1051 uint16 opnum = SVAL(data,22);
1053 int pkttype = CVAL(data, 2);
1054 if (pkttype == 0x0b) /* RPC BIND */
1056 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1057 LsarpcTNP1(data,rdata,rdata_len);
1061 DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum));
1064 case LSA_OPENPOLICY:
1066 DEBUG(3,("LSA_OPENPOLICY\n"));
1067 api_lsa_open_policy(param, data, rdata, rdata_len);
1068 make_rpc_reply(data, *rdata, *rdata_len);
1073 case LSA_QUERYINFOPOLICY:
1075 DEBUG(3,("LSA_QUERYINFOPOLICY\n"));
1077 api_lsa_query_info(param, data, rdata, rdata_len);
1078 make_rpc_reply(data, *rdata, *rdata_len);
1083 case LSA_ENUMTRUSTDOM:
1085 char *q = *rdata + 0x18;
1087 DEBUG(3,("LSA_ENUMTRUSTDOM\n"));
1089 initrpcreply(data, *rdata);
1091 SIVAL(q, 0, 0); /* enumeration context */
1092 SIVAL(q, 0, 4); /* entries read */
1093 SIVAL(q, 0, 8); /* trust information */
1095 endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len);
1102 char *q = *rdata + 0x18;
1104 DEBUG(3,("LSA_CLOSE\n"));
1106 initrpcreply(data, *rdata);
1114 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1119 case LSA_OPENSECRET:
1121 char *q = *rdata + 0x18;
1122 DEBUG(3,("LSA_OPENSECRET\n"));
1124 initrpcreply(data, *rdata);
1132 endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len);
1137 case LSA_LOOKUPSIDS:
1139 DEBUG(3,("LSA_OPENSECRET\n"));
1140 api_lsa_lookup_sids(param, data, rdata, rdata_len);
1141 make_rpc_reply(data, *rdata, *rdata_len);
1146 case LSA_LOOKUPNAMES:
1148 DEBUG(3,("LSA_LOOKUPNAMES\n"));
1149 api_lsa_lookup_names(param, data, rdata, rdata_len);
1150 make_rpc_reply(data, *rdata, *rdata_len);
1157 DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum));
1164 static BOOL update_dcinfo(struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct)
1166 struct smb_passwd *smb_pass = get_smbpwnam(mach_acct);
1169 if (smb_pass != NULL)
1171 memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw));
1175 /* No such machine account. Should error out here, but we'll
1176 print and carry on */
1177 DEBUG(1,("No account in domain for %s\n", mach_acct));
1183 for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]);
1184 DEBUG(4,("pass %s %s\n", mach_acct, foo));
1187 /* from client / server challenges and md4 password, generate sess key */
1188 cred_session_key(&(dc->clnt_chal), &(dc->srv_chal),
1189 dc->md4pw, dc->sess_key);
1191 /* copy the client credentials for later use */
1192 memcpy(dc->srv_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
1193 memcpy(dc->srv_cred.data, clnt_chal->data, sizeof(clnt_chal->data));
1195 /* create a server challenge for the client */
1196 /* PAXX: set these to random values. */
1197 /* lkcl: paul, you mentioned that it doesn't really matter much */
1198 for (i = 0; i < 8; i++)
1200 dc->srv_chal.data[i] = 0xA5;
1206 static void api_lsa_req_chal( user_struct *vuser,
1207 char *param, char *data,
1208 char **rdata, int *rdata_len )
1216 /* grab the challenge... */
1217 lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4, 0);
1219 fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer));
1221 strcat(mach_acct, "$");
1223 update_dcinfo(&(vuser->dc), &(q_r.clnt_chal), mach_acct);
1225 /* construct reply. return status is always 0x0 */
1226 reply_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata + 0x18,
1227 &(vuser->dc.srv_chal));
1229 /* construct header, now that we know the reply length */
1230 reply_len += make_rpc_reply(data, *rdata, reply_len);
1232 *rdata_len = reply_len;
1235 static void api_lsa_auth_2( user_struct *vuser,
1236 char *param, char *data,
1237 char **rdata, int *rdata_len )
1247 /* grab the challenge... */
1248 lsa_io_q_auth_2(True, &q_a, data + 0x18, data + 0x18, 4, 0);
1250 /* check that the client credentials are valid */
1251 cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
1252 &(vuser->dc.srv_cred), srv_time);
1254 /* create server credentials for inclusion in the reply */
1255 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), srv_time, &srv_chal);
1257 /* construct reply. */
1258 reply_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata + 0x18,
1261 /* construct header, now that we know the reply length */
1262 reply_len += make_rpc_reply(data, *rdata, reply_len);
1264 *rdata_len = reply_len;
1268 static BOOL deal_with_credentials(user_struct *vuser,
1269 DOM_CRED *clnt_cred, DOM_CRED *srv_cred)
1271 UTIME new_clnt_time;
1273 /* doesn't matter that server time is 0 */
1274 srv_cred->timestamp.time = 0;
1276 /* check that the client credentials are valid */
1277 if (cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key,
1278 &(vuser->dc.srv_cred), clnt_cred->timestamp))
1283 /* increment client time by one second */
1284 new_clnt_time.time = clnt_cred->timestamp.time + 1;
1286 /* create server credentials for inclusion in the reply */
1287 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time,
1288 &(srv_cred->challenge));
1290 /* update the client and server credentials, for use next time... */
1291 *(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time );
1296 static void api_lsa_srv_pwset( user_struct *vuser,
1297 char *param, char *data,
1298 char **rdata, int *rdata_len )
1301 LSA_Q_SRV_PWSET q_a;
1305 /* grab the challenge and encrypted password ... */
1306 lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4, 0);
1308 /* checks and updates credentials. creates reply credentials */
1309 deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred);
1311 /* construct reply. always indicate failure. nt keeps going... */
1312 reply_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata + 0x18,
1314 NT_STATUS_WRONG_PASSWORD|0xC000000);
1316 /* construct header, now that we know the reply length */
1317 reply_len += make_rpc_reply(data, *rdata, reply_len);
1319 *rdata_len = reply_len;
1323 static void api_lsa_sam_logoff( user_struct *vuser,
1324 char *param, char *data,
1325 char **rdata, int *rdata_len )
1328 LSA_Q_SAM_LOGOFF q_l;
1332 /* grab the challenge... */
1333 lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1335 /* checks and updates credentials. creates reply credentials */
1336 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred);
1338 /* construct reply. always indicate success */
1339 reply_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata + 0x18,
1343 /* construct header, now that we know the reply length */
1344 reply_len += make_rpc_reply(data, *rdata, reply_len);
1346 *rdata_len = reply_len;
1350 static void api_lsa_sam_logon( user_struct *vuser,
1351 char *param, char *data,
1352 char **rdata, int *rdata_len )
1355 LSA_Q_SAM_LOGON q_l;
1356 LSA_USER_INFO usr_info;
1357 LSA_USER_INFO *p_usr_info = NULL;
1361 lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1363 /* checks and updates credentials. creates reply credentials */
1364 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds);
1369 pstring logon_script;
1370 pstring profile_path;
1374 pstring my_workgroup;
1377 extern pstring myname;
1379 dummy_time.low = 0xffffffff;
1380 dummy_time.high = 0x7fffffff;
1382 get_myname(myname, NULL);
1384 pstrcpy(logon_script, lp_logon_script());
1385 pstrcpy(profile_path, lp_logon_path ());
1386 pstrcpy(dom_sid , lp_domainsid ());
1387 pstrcpy(my_workgroup, lp_workgroup ());
1389 pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer));
1390 pstrcpy(my_name , myname );
1393 pstrcpy(home_drive , "a:" );
1395 #if (defined(NETGROUP) && defined(AUTOMOUNT))
1396 pstrcpy(home_dir , vuser->home_share);
1398 pstrcpy(home_dir , "\\\\%L\\%U");
1399 standard_sub_basic(home_dir);
1402 p_usr_info = &usr_info;
1404 make_lsa_user_info(p_usr_info,
1406 &dummy_time, /* logon_time */
1407 &dummy_time, /* logoff_time */
1408 &dummy_time, /* kickoff_time */
1409 &dummy_time, /* pass_last_set_time */
1410 &dummy_time, /* pass_can_change_time */
1411 &dummy_time, /* pass_must_change_time */
1413 username, /* user_name */
1414 vuser->real_name, /* full_name */
1415 logon_script, /* logon_script */
1416 profile_path, /* profile_path */
1417 home_dir, /* home_dir */
1418 home_drive, /* dir_drive */
1420 0, /* logon_count */
1421 0, /* bad_pw_count */
1423 vuser->uid, /* uint32 user_id */
1424 vuser->gid, /* uint32 group_id */
1425 0, /* uint32 num_groups */
1426 NULL, /* DOM_GID *gids */
1427 0x20, /* uint32 user_flgs */
1429 NULL, /* char sess_key[16] */
1431 my_name, /* char *logon_srv */
1432 my_workgroup, /* char *logon_dom */
1434 dom_sid, /* char *dom_sid */
1435 NULL); /* char *other_sids */
1438 reply_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata + 0x18,
1439 &srv_creds, p_usr_info);
1441 /* construct header, now that we know the reply length */
1442 reply_len += make_rpc_reply(data, *rdata, reply_len);
1444 *rdata_len = reply_len;
1450 DEBUG(1,("LSASAMLOGON\n"));
1451 dump_data(1,data,128);
1454 DEBUG(1,("SMLOG %d\n", __LINE__));
1455 q = skip_unicode_string(logonsrv,1)+16;
1456 q = align4(q, data);
1458 q = skip_unicode_string(unicomp,1)+4;
1459 DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n",
1460 __LINE__, unistr(logonsrv), unistr(unicomp)));
1461 q = align4(q, data);
1463 DEBUG(1,("SMLOG %d\n", __LINE__));
1465 DEBUG(1,("SMLOG %d\n", __LINE__));
1467 checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
1469 rtncred[0] = qIVAL; /* all these are ignored */
1470 DEBUG(1,("SMLOG %d\n", __LINE__));
1474 DEBUG(1,("SMLOG %d\n", __LINE__));
1482 dommaxlen = qSVAL; q += 4;
1483 paramcontrol = qIVAL;
1484 logonid[0] = qIVAL; /* low part */
1485 logonid[1] = qIVAL; /* high part */
1487 usernamelen = qSVAL;
1489 DEBUG(1,("SMLOG %d\n", __LINE__));
1490 usernamemaxlen = qSVAL; q += 4;
1492 DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n",
1493 usernamelen, usernamemaxlen, dommaxlen));
1498 wsmaxlen = qSVAL; q += 4;
1499 rc4lmowfpass = q; q += 16;
1500 rc4ntowfpass = q; q += 16;
1502 q += 12; domain = q; q += dommaxlen + 12;
1503 q = align4(q, data);
1504 username = q; q += usernamemaxlen + 12;
1505 q = align4(q, data);
1507 DEBUG(1,("domain=%s username=%s ws=%s\n",
1508 unistr(domain), unistr(username),
1512 DEBUG(0,("unknown switch in SAMLOGON %d\n",
1515 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]);
1516 DEBUG(1,("userNAME %s [%s]\n", foo, username));
1517 DEBUG(1,("SMLOG %d\n", __LINE__));
1519 qSIVAL(0x16a4b4); /* magic buffer pointer ? */
1520 makecred(cnum, clnttime+1, q);
1521 dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1;
1523 qSIVAL(0); /* timestamp. client doesn't care */
1524 qSSVAL(3); /* switch value 3. May be others? */
1525 qSSVAL(0); /* undocumented */
1526 DEBUG(1,("SMLOG %d\n", __LINE__));
1528 memset(rc4key, 0, sizeof rc4key);
1529 SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]);
1530 SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]);
1531 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]);
1532 DEBUG(1,("rc4ntowf %s\n", foo));
1533 arcfour_init(&c, rc4key, sizeof rc4key);
1534 arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass);
1535 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]);
1536 DEBUG(1,("ntowf %s\n", foo));
1538 if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) {
1539 qSIVAL(0); /* no buffer */
1540 qSCVAL(1); /* Authoratitive. Change if passthrough? */
1541 qSCVAL(0); /* pad for above boolean */
1542 qSSVAL(0); /* pad for above boolean */
1544 endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len);
1548 qSIVAL(2); /* another magic bufptr? */
1549 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo));
1550 qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]);
1551 qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]);
1552 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1]));
1553 qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]);
1554 qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]);
1555 qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]);
1556 qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]);
1557 DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename));
1558 qunihdr(userinfo->effectivename);
1559 qunihdr(userinfo->fullname);
1560 DEBUG(1,("SMLOG %d\n", __LINE__));
1561 qunihdr(userinfo->logonscript);
1562 qunihdr(userinfo->profilepath);
1563 qunihdr(userinfo->homedirectory);
1564 qunihdr(userinfo->homedirectorydrive);
1565 DEBUG(1,("SMLOG %d\n", __LINE__));
1566 qSSVAL(userinfo->logoncount);
1567 qSSVAL(userinfo->badpwcount);
1568 qSIVAL(userinfo->uid);
1569 qSIVAL(userinfo->gid);
1570 DEBUG(1,("SMLOG %d\n", __LINE__));
1571 qSIVAL(userinfo->ngroups);
1572 qSIVAL(8); /* ptr to groups */
1573 qSIVAL(userinfo->userflags);
1574 DEBUG(1,("SMLOG %d\n", __LINE__));
1575 qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */
1576 qunihdr(userinfo->logonserver);
1577 qunihdr(userinfo->logondomain);
1578 DEBUG(1,("SMLOG %d\n", __LINE__));
1579 qSIVAL(2); /* logon domain id ptr */
1580 DEBUG(1,("SMLOG %d\n", __LINE__));
1581 memset(q,0,40); q += 40; /* expansion room */
1582 DEBUG(1,("SMLOG %d\n", __LINE__));
1583 qSIVAL(userinfo->nsids);
1584 DEBUG(1,("SMLOG %d\n", __LINE__));
1585 qSIVAL(0); /* ptr to sids and values */
1586 DEBUG(1,("SMLOG %d\n", __LINE__));
1587 qunistr(userinfo->effectivename);
1588 DEBUG(1,("SMLOG %d\n", __LINE__));
1589 qunistr(userinfo->fullname);
1590 DEBUG(1,("SMLOG %d\n", __LINE__));
1591 qunistr(userinfo->logonscript);
1592 DEBUG(1,("SMLOG %d\n", __LINE__));
1593 qunistr(userinfo->profilepath);
1594 qunistr(userinfo->homedirectory);
1595 qunistr(userinfo->homedirectorydrive);
1596 DEBUG(1,("SMLOG %d\n", __LINE__));
1597 qSIVAL(userinfo->ngroups);
1598 for (i = 0; i < userinfo->ngroups; i++)
1600 qSIVAL(userinfo->groups[i].gid);
1601 qSIVAL(userinfo->groups[i].attr);
1603 qunistr(userinfo->logonserver);
1604 qunistr(userinfo->logondomain);
1605 for (i = 0; i < userinfo->nsids; i++)
1607 /* put the extra sids: PAXX: TODO */
1609 /* Assumption. This is the only domain, sending our SID */
1610 /* PAXX: may want to do passthrough later */
1611 strcpy(domsid,lp_domainsid());
1612 DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid));
1613 /* assume, but should check, that domsid starts "S-" */
1614 p = strtok(domsid+2,"-");
1616 DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision));
1617 identauth = atoi(strtok(0,"-"));
1618 DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth));
1620 while (p = strtok(0, "-"))
1621 subauths[numsubauths++] = atoi(p);
1622 qSIVAL(numsubauths);
1624 qSCVAL(numsubauths);
1625 qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */
1626 qRSIVAL(identauth); /* next 4 bytes */
1627 DEBUG(1,("SMLOG %d\n", __LINE__));
1628 for (i = 0; i < numsubauths; i++)
1630 qSIVAL(subauths[i]);
1632 qSCVAL(1); /* Authoratitive. Change if passthrough? */
1633 qSCVAL(0); /* pad for above boolean */
1634 qSSVAL(0); /* pad for above boolean */
1636 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1640 BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
1641 int mdrcnt,int mprcnt,
1642 char **rdata,char **rparam,
1643 int *rdata_len,int *rparam_len)
1649 DEBUG(5,("api_netlogrpcTNP data:%x\n", data));
1651 if (data == NULL) return False;
1653 opnum = SVAL(data,22);
1654 pkttype = CVAL(data, 2);
1656 if (pkttype == 0x0b) /* RPC BIND */
1658 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1659 LsarpcTNP1(data,rdata,rdata_len);
1663 DEBUG(4,("netlogon TransactNamedPipe op %x\n", opnum));
1665 if ((vuser = get_valid_user_struct(uid)) == NULL) return False;
1667 DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
1668 #if defined(NETGROUP) && defined(AUTOMOUNT)
1669 DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
1676 DEBUG(3,("LSA_REQCHAL\n"));
1677 api_lsa_req_chal(vuser, param, data, rdata, rdata_len);
1683 DEBUG(3,("LSA_AUTH2\n"));
1684 api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
1690 DEBUG(3,("LSA_SRVPWSET\n"));
1691 api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
1697 DEBUG(3,("LSA_SAMLOGON\n"));
1698 api_lsa_sam_logon(vuser, param, data, rdata, rdata_len);
1704 DEBUG(3,("LSA_SAMLOGOFF\n"));
1705 api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len);
1711 DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
1719 #endif /* NTDOMAIN */