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 = 0x10; /* 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) - q;
504 static int lsa_reply_open_policy(char *q, char *base)
510 static char handle[20] =
511 { 0x00, 0x00, 0x00, 0x00,
512 0x2f, 0x79, 0x0a, 0x81,
513 0xd5, 0x17, 0xd1, 0x11,
514 0x80, 0xaf, 0x96, 0xcd,
515 0x50, 0xf8, 0xbc, 0x6c
517 /* set up the LSA QUERY INFO response */
518 /* bzero(&(r_o.pol.data), POL_HND_SIZE); */
519 for (i = 0; i < POL_HND_SIZE; i++)
521 r_o.pol.data[i] = handle[i];
525 /* store the response in the SMB stream */
526 q = lsa_io_r_open_pol(False, &r_o, q, base, 4, 0);
528 /* return length of SMB data stored */
532 static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate)
534 hdr->uni_max_len = max_len;
535 hdr->uni_str_len = len;
536 hdr->undoc = terminate;
539 static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate)
541 make_uni_hdr(&(hdr->unihdr), max_len, len, terminate);
542 hdr->undoc_buffer = len > 0 ? 1 : 0;
545 static void make_unistr(UNISTR *str, char *buf)
547 /* store the string (null-terminated copy) */
548 PutUniCode((char *)(str->buffer), buf);
551 static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate)
553 /* set up string lengths. add one if string is not null-terminated */
554 str->uni_max_len = len + (terminate != 0 ? 1 : 0);
556 str->uni_str_len = len;
558 /* store the string (null-terminated copy) */
559 PutUniCode((char *)str->buffer, buf);
561 /* overwrite the last character: some strings are terminated with 4 not 0 */
562 str->buffer[len] = (uint16)terminate;
565 static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid)
573 static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str)
575 int len_sid_str = strlen(sid_str);
579 make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0);
580 make_unistr (&(sid2->str), sid_str);
583 static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid)
585 int domlen = strlen(dom_name);
587 d_q->uni_dom_max_len = domlen * 2;
589 d_q->uni_dom_str_len = domlen * 2;
591 d_q->buffer_dom_name = 0; /* domain buffer pointer */
592 d_q->buffer_dom_sid = 0; /* domain sid pointer */
594 /* NOT null-terminated: 4-terminated instead! */
595 make_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4);
597 make_dom_sid(&(d_q->dom_sid), dom_sid);
600 static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base,
601 char *dom_name, char *dom_sid)
604 LSA_R_QUERY_INFO r_q;
606 /* set up the LSA QUERY INFO response */
608 r_q.undoc_buffer = 1; /* not null */
609 r_q.info_class = q_q->info_class;
611 make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
615 /* store the response in the SMB stream */
616 q = lsa_io_r_query(False, &r_q, q, base, 4, 0);
618 /* return length of SMB data stored */
622 /* pretty much hard-coded choice of "other" sids, unfortunately... */
623 static void make_dom_ref(DOM_R_REF *ref,
624 char *dom_name, char *dom_sid,
625 char *other_sid1, char *other_sid2, char *other_sid3)
627 int len_dom_name = strlen(dom_name);
628 int len_other_sid1 = strlen(other_sid1);
629 int len_other_sid2 = strlen(other_sid2);
630 int len_other_sid3 = strlen(other_sid3);
632 ref->undoc_buffer = 1;
633 ref->num_ref_doms_1 = 4;
634 ref->buffer_dom_name = 1;
635 ref->max_entries = 32;
636 ref->num_ref_doms_2 = 4;
638 make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0);
639 make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0);
640 make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0);
641 make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0);
643 if (dom_name != NULL)
645 make_unistr(&(ref->uni_dom_name), dom_name);
648 make_dom_sid(&(ref->ref_dom[0]), dom_sid );
649 make_dom_sid(&(ref->ref_dom[1]), other_sid1);
650 make_dom_sid(&(ref->ref_dom[2]), other_sid2);
651 make_dom_sid(&(ref->ref_dom[3]), other_sid3);
654 static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l,
655 int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
656 char *dom_name, char *dom_sid,
657 char *other_sid1, char *other_sid2, char *other_sid3)
661 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
662 other_sid1, other_sid2, other_sid3);
664 r_l->num_entries = num_entries;
665 r_l->undoc_buffer = 1;
666 r_l->num_entries2 = num_entries;
668 for (i = 0; i < num_entries; i++)
670 make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]);
673 r_l->num_entries3 = num_entries;
676 static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
677 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
678 char *dom_name, char *dom_sid,
679 char *other_sid1, char *other_sid2, char *other_sid3)
683 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
684 other_sid1, other_sid2, other_sid3);
686 r_l->num_entries = num_entries;
687 r_l->undoc_buffer = 1;
688 r_l->num_entries2 = num_entries;
690 for (i = 0; i < num_entries; i++)
692 make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]);
695 r_l->num_entries3 = num_entries;
698 static int lsa_reply_lookup_sids(char *q, char *base,
699 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
700 char *dom_name, char *dom_sid,
701 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 */
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)
724 LSA_R_LOOKUP_RIDS r_l;
726 /* set up the LSA Lookup RIDs response */
727 make_reply_lookup_rids(&r_l, num_entries, dom_rids,
728 dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
731 /* store the response in the SMB stream */
732 q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4, 0);
734 /* return length of SMB data stored */
738 static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c,
739 DOM_CHAL *srv_chal, int status)
741 memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(r_c->srv_chal.data));
742 r_c->status = status;
745 static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
751 /* set up the LSA REQUEST CHALLENGE response */
753 make_lsa_r_req_chal(&r_c, srv_chal, 0);
755 /* store the response in the SMB stream */
756 q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0);
758 /* return length of SMB data stored */
762 static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
763 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
765 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
766 memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
767 r_a->status = status;
770 static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
771 DOM_CHAL *resp_cred, int status)
776 /* set up the LSA AUTH 2 response */
778 make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
780 /* store the response in the SMB stream */
781 q = lsa_io_r_auth_2(False, &r_a, q, base, 4, 0);
783 /* return length of SMB data stored */
787 static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a,
788 DOM_CRED *srv_cred, int status)
790 memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred));
791 r_a->status = status;
794 static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
795 DOM_CRED *srv_cred, int status)
800 /* set up the LSA Server Password Set response */
801 make_lsa_r_srv_pwset(&r_s, srv_cred, status);
803 /* store the response in the SMB stream */
804 q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0);
806 /* return length of SMB data stored */
810 static void make_lsa_user_info(LSA_USER_INFO *usr,
814 NTTIME *kickoff_time,
815 NTTIME *pass_last_set_time,
816 NTTIME *pass_can_change_time,
817 NTTIME *pass_must_change_time,
841 char *other_sids) /* space-delimited set of SIDs */
843 /* only cope with one "other" sid, right now. */
844 /* need to count the number of space-delimited sids */
846 int num_other_sids = other_sids != NULL ? 1 : 0;
848 int len_user_name = strlen(user_name );
849 int len_full_name = strlen(full_name );
850 int len_logon_script = strlen(logon_script);
851 int len_profile_path = strlen(profile_path);
852 int len_home_dir = strlen(home_dir );
853 int len_dir_drive = strlen(dir_drive );
855 int len_logon_srv = strlen(logon_srv);
856 int len_logon_dom = strlen(logon_dom);
858 usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */
860 usr->logon_time = *logon_time;
861 usr->logoff_time = *logoff_time;
862 usr->kickoff_time = *kickoff_time;
863 usr->pass_last_set_time = *pass_last_set_time;
864 usr->pass_can_change_time = *pass_can_change_time;
865 usr->pass_must_change_time = *pass_must_change_time;
867 make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4);
868 make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4);
869 make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
870 make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
871 make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4);
872 make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4);
874 usr->logon_count = logon_count;
875 usr->bad_pw_count = bad_pw_count;
877 usr->user_id = user_id;
878 usr->group_id = group_id;
879 usr->num_groups = num_groups;
880 usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */
881 usr->user_flgs = user_flgs;
883 if (sess_key != NULL)
885 memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key));
889 bzero(usr->sess_key, sizeof(usr->sess_key));
892 make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
893 make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
895 usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
897 bzero(usr->padding, sizeof(usr->padding));
899 usr->num_other_sids = num_other_sids;
900 usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
902 make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0);
903 make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0);
904 make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0);
905 make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0);
906 make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0);
907 make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0);
909 usr->num_groups2 = num_groups;
910 for (i = 0; i < num_groups; i++)
912 usr->gids[i] = gids[i];
915 make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0);
916 make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0);
918 make_dom_sid(&(usr->dom_sid), dom_sid);
919 make_dom_sid(&(usr->other_sids[0]), other_sids);
923 static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
924 DOM_CRED *srv_cred, LSA_USER_INFO *user_info)
929 /* XXXX maybe we want to say 'no', reject the client's credentials */
930 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
931 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
933 /* store the user information, if there is any. */
934 r_s.user = user_info;
935 r_s.buffer_user = user_info != NULL ? 1 : 0;
936 r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER);
938 /* store the response in the SMB stream */
939 q = lsa_io_r_sam_logon(False, &r_s, q, base, 4, 0);
941 /* return length of SMB data stored */
946 static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
951 LSA_R_SAM_LOGOFF r_s;
953 /* XXXX maybe we want to say 'no', reject the client's credentials */
954 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
955 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
959 /* store the response in the SMB stream */
960 q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4, 0);
962 /* return length of SMB data stored */
967 static void api_lsa_open_policy( char *param, char *data,
968 char **rdata, int *rdata_len )
970 /* we might actually want to decode the query, but it's not necessary */
971 /* lsa_io_q_open_policy(...); */
973 /* construct a 20 byte policy handle. return length*/
974 *rdata_len = lsa_reply_open_policy(*rdata + 0x18, *rdata);
977 static int api_lsa_query_info( char *param, char *data,
978 char **rdata, int *rdata_len )
980 LSA_Q_QUERY_INFO q_i;
984 /* grab the info class and policy handle */
985 lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4, 0);
987 pstrcpy(dom_name, lp_workgroup());
988 pstrcpy(dom_sid , lp_domainsid());
990 /* construct reply. return status is always 0x0 */
991 return lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata,
995 static void api_lsa_lookup_sids( char *param, char *data,
996 char **rdata, int *rdata_len )
999 LSA_Q_LOOKUP_SIDS q_l;
1002 fstring dom_sids[MAX_LOOKUP_SIDS];
1004 /* grab the info class and policy handle */
1005 lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1007 pstrcpy(dom_name, lp_workgroup());
1008 pstrcpy(dom_sid , lp_domainsid());
1010 /* convert received SIDs to strings, so we can do them. */
1011 for (i = 0; i < q_l.num_entries; i++)
1013 fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i])));
1016 /* construct reply. return status is always 0x0 */
1017 *rdata_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata,
1018 q_l.num_entries, dom_sids, /* text-converted SIDs */
1019 dom_name, dom_sid, /* domain name, domain SID */
1020 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1023 static void api_lsa_lookup_names( char *param, char *data,
1024 char **rdata, int *rdata_len )
1027 LSA_Q_LOOKUP_RIDS q_l;
1030 uint32 dom_rids[MAX_LOOKUP_SIDS];
1032 /* grab the info class and policy handle */
1033 lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1035 pstrcpy(dom_name, lp_workgroup());
1036 pstrcpy(dom_sid , lp_domainsid());
1038 /* convert received RIDs to strings, so we can do them. */
1039 for (i = 0; i < q_l.num_entries; i++)
1041 char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
1042 dom_rids[i] = name_to_rid(user_name);
1045 /* construct reply. return status is always 0x0 */
1046 *rdata_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata,
1047 q_l.num_entries, dom_rids, /* text-converted SIDs */
1048 dom_name, dom_sid, /* domain name, domain SID */
1049 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1052 BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
1053 int mdrcnt,int mprcnt,
1054 char **rdata,char **rparam,
1055 int *rdata_len,int *rparam_len)
1057 uint16 opnum = SVAL(data,22);
1059 int pkttype = CVAL(data, 2);
1060 if (pkttype == 0x0b) /* RPC BIND */
1062 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1063 LsarpcTNP1(data,rdata,rdata_len);
1067 DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum));
1070 case LSA_OPENPOLICY:
1072 DEBUG(3,("LSA_OPENPOLICY\n"));
1073 api_lsa_open_policy(param, data, rdata, rdata_len);
1074 make_rpc_reply(data, *rdata, *rdata_len);
1079 case LSA_QUERYINFOPOLICY:
1081 DEBUG(3,("LSA_QUERYINFOPOLICY\n"));
1083 api_lsa_query_info(param, data, rdata, rdata_len);
1084 make_rpc_reply(data, *rdata, *rdata_len);
1089 case LSA_ENUMTRUSTDOM:
1091 char *q = *rdata + 0x18;
1093 DEBUG(3,("LSA_ENUMTRUSTDOM\n"));
1095 initrpcreply(data, *rdata);
1097 SIVAL(q, 0, 0); /* enumeration context */
1098 SIVAL(q, 0, 4); /* entries read */
1099 SIVAL(q, 0, 8); /* trust information */
1101 endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len);
1108 char *q = *rdata + 0x18;
1110 DEBUG(3,("LSA_CLOSE\n"));
1112 initrpcreply(data, *rdata);
1120 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1125 case LSA_OPENSECRET:
1127 char *q = *rdata + 0x18;
1128 DEBUG(3,("LSA_OPENSECRET\n"));
1130 initrpcreply(data, *rdata);
1138 endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len);
1143 case LSA_LOOKUPSIDS:
1145 DEBUG(3,("LSA_OPENSECRET\n"));
1146 api_lsa_lookup_sids(param, data, rdata, rdata_len);
1147 make_rpc_reply(data, *rdata, *rdata_len);
1152 case LSA_LOOKUPNAMES:
1154 DEBUG(3,("LSA_LOOKUPNAMES\n"));
1155 api_lsa_lookup_names(param, data, rdata, rdata_len);
1156 make_rpc_reply(data, *rdata, *rdata_len);
1163 DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum));
1170 static BOOL update_dcinfo(struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct)
1172 struct smb_passwd *smb_pass = get_smbpwnam(mach_acct);
1175 if (smb_pass != NULL)
1177 memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw));
1181 /* No such machine account. Should error out here, but we'll
1182 print and carry on */
1183 DEBUG(1,("No account in domain for %s\n", mach_acct));
1189 for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]);
1190 DEBUG(4,("pass %s %s\n", mach_acct, foo));
1193 /* from client / server challenges and md4 password, generate sess key */
1194 cred_session_key(&(dc->clnt_chal), &(dc->srv_chal),
1195 dc->md4pw, dc->sess_key);
1197 /* copy the client credentials for later use */
1198 memcpy(dc->srv_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
1199 memcpy(dc->srv_cred.data, clnt_chal->data, sizeof(clnt_chal->data));
1201 /* create a server challenge for the client */
1202 /* PAXX: set these to random values. */
1203 /* lkcl: paul, you mentioned that it doesn't really matter much */
1204 for (i = 0; i < 8; i++)
1206 dc->srv_chal.data[i] = 0xA5;
1212 static void api_lsa_req_chal( user_struct *vuser,
1213 char *param, char *data,
1214 char **rdata, int *rdata_len )
1222 /* grab the challenge... */
1223 lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4, 0);
1225 fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer));
1227 strcat(mach_acct, "$");
1229 update_dcinfo(&(vuser->dc), &(q_r.clnt_chal), mach_acct);
1231 /* construct reply. return status is always 0x0 */
1232 reply_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata + 0x18,
1233 &(vuser->dc.srv_chal));
1235 /* construct header, now that we know the reply length */
1236 reply_len += make_rpc_reply(data, *rdata, reply_len);
1238 *rdata_len = reply_len;
1241 static void api_lsa_auth_2( user_struct *vuser,
1242 char *param, char *data,
1243 char **rdata, int *rdata_len )
1253 /* grab the challenge... */
1254 lsa_io_q_auth_2(True, &q_a, data + 0x18, data + 0x18, 4, 0);
1256 /* check that the client credentials are valid */
1257 cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
1258 &(vuser->dc.srv_cred), srv_time);
1260 /* create server credentials for inclusion in the reply */
1261 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), srv_time, &srv_chal);
1263 /* construct reply. */
1264 reply_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata + 0x18,
1267 /* construct header, now that we know the reply length */
1268 reply_len += make_rpc_reply(data, *rdata, reply_len);
1270 *rdata_len = reply_len;
1274 static BOOL deal_with_credentials(user_struct *vuser,
1275 DOM_CRED *clnt_cred, DOM_CRED *srv_cred)
1277 UTIME new_clnt_time;
1279 /* doesn't matter that server time is 0 */
1280 srv_cred->timestamp.time = 0;
1282 /* check that the client credentials are valid */
1283 if (cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key,
1284 &(vuser->dc.srv_cred), clnt_cred->timestamp))
1289 /* increment client time by one second */
1290 new_clnt_time.time = clnt_cred->timestamp.time + 1;
1292 /* create server credentials for inclusion in the reply */
1293 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time,
1294 &(srv_cred->challenge));
1296 /* update the client and server credentials, for use next time... */
1297 *(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time );
1302 static void api_lsa_srv_pwset( user_struct *vuser,
1303 char *param, char *data,
1304 char **rdata, int *rdata_len )
1307 LSA_Q_SRV_PWSET q_a;
1311 /* grab the challenge and encrypted password ... */
1312 lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4, 0);
1314 /* checks and updates credentials. creates reply credentials */
1315 deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred);
1317 /* construct reply. always indicate failure. nt keeps going... */
1318 reply_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata + 0x18,
1320 NT_STATUS_WRONG_PASSWORD|0xC000000);
1322 /* construct header, now that we know the reply length */
1323 reply_len += make_rpc_reply(data, *rdata, reply_len);
1325 *rdata_len = reply_len;
1329 static void api_lsa_sam_logoff( user_struct *vuser,
1330 char *param, char *data,
1331 char **rdata, int *rdata_len )
1334 LSA_Q_SAM_LOGOFF q_l;
1338 /* grab the challenge... */
1339 lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1341 /* checks and updates credentials. creates reply credentials */
1342 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred);
1344 /* construct reply. always indicate success */
1345 reply_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata + 0x18,
1349 /* construct header, now that we know the reply length */
1350 reply_len += make_rpc_reply(data, *rdata, reply_len);
1352 *rdata_len = reply_len;
1356 static void api_lsa_sam_logon( user_struct *vuser,
1357 char *param, char *data,
1358 char **rdata, int *rdata_len )
1361 LSA_Q_SAM_LOGON q_l;
1362 LSA_USER_INFO usr_info;
1363 LSA_USER_INFO *p_usr_info = NULL;
1367 lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4, 0);
1369 /* checks and updates credentials. creates reply credentials */
1370 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds);
1375 pstring logon_script;
1376 pstring profile_path;
1380 pstring my_workgroup;
1383 extern pstring myname;
1385 dummy_time.low = 0xffffffff;
1386 dummy_time.high = 0x7fffffff;
1388 get_myname(myname, NULL);
1390 pstrcpy(logon_script, lp_logon_script());
1391 pstrcpy(profile_path, lp_logon_path ());
1392 pstrcpy(dom_sid , lp_domainsid ());
1393 pstrcpy(my_workgroup, lp_workgroup ());
1395 pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer));
1396 pstrcpy(my_name , myname );
1399 pstrcpy(home_drive , "a:" );
1401 #if (defined(NETGROUP) && defined(AUTOMOUNT))
1402 pstrcpy(home_dir , vuser->home_share);
1404 pstrcpy(home_dir , "\\\\%L\\%U");
1405 standard_sub_basic(home_dir);
1408 p_usr_info = &usr_info;
1410 make_lsa_user_info(p_usr_info,
1412 &dummy_time, /* logon_time */
1413 &dummy_time, /* logoff_time */
1414 &dummy_time, /* kickoff_time */
1415 &dummy_time, /* pass_last_set_time */
1416 &dummy_time, /* pass_can_change_time */
1417 &dummy_time, /* pass_must_change_time */
1419 username, /* user_name */
1420 vuser->real_name, /* full_name */
1421 logon_script, /* logon_script */
1422 profile_path, /* profile_path */
1423 home_dir, /* home_dir */
1424 home_drive, /* dir_drive */
1426 0, /* logon_count */
1427 0, /* bad_pw_count */
1429 vuser->uid, /* uint32 user_id */
1430 vuser->gid, /* uint32 group_id */
1431 0, /* uint32 num_groups */
1432 NULL, /* DOM_GID *gids */
1433 0x20, /* uint32 user_flgs */
1435 NULL, /* char sess_key[16] */
1437 my_name, /* char *logon_srv */
1438 my_workgroup, /* char *logon_dom */
1440 dom_sid, /* char *dom_sid */
1441 NULL); /* char *other_sids */
1444 reply_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata + 0x18,
1445 &srv_creds, p_usr_info);
1447 /* construct header, now that we know the reply length */
1448 reply_len += make_rpc_reply(data, *rdata, reply_len);
1450 *rdata_len = reply_len;
1456 DEBUG(1,("LSASAMLOGON\n"));
1457 dump_data(1,data,128);
1460 DEBUG(1,("SMLOG %d\n", __LINE__));
1461 q = skip_unicode_string(logonsrv,1)+16;
1462 q = align4(q, data);
1464 q = skip_unicode_string(unicomp,1)+4;
1465 DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n",
1466 __LINE__, unistr(logonsrv), unistr(unicomp)));
1467 q = align4(q, data);
1469 DEBUG(1,("SMLOG %d\n", __LINE__));
1471 DEBUG(1,("SMLOG %d\n", __LINE__));
1473 checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
1475 rtncred[0] = qIVAL; /* all these are ignored */
1476 DEBUG(1,("SMLOG %d\n", __LINE__));
1480 DEBUG(1,("SMLOG %d\n", __LINE__));
1488 dommaxlen = qSVAL; q += 4;
1489 paramcontrol = qIVAL;
1490 logonid[0] = qIVAL; /* low part */
1491 logonid[1] = qIVAL; /* high part */
1493 usernamelen = qSVAL;
1495 DEBUG(1,("SMLOG %d\n", __LINE__));
1496 usernamemaxlen = qSVAL; q += 4;
1498 DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n",
1499 usernamelen, usernamemaxlen, dommaxlen));
1504 wsmaxlen = qSVAL; q += 4;
1505 rc4lmowfpass = q; q += 16;
1506 rc4ntowfpass = q; q += 16;
1508 q += 12; domain = q; q += dommaxlen + 12;
1509 q = align4(q, data);
1510 username = q; q += usernamemaxlen + 12;
1511 q = align4(q, data);
1513 DEBUG(1,("domain=%s username=%s ws=%s\n",
1514 unistr(domain), unistr(username),
1518 DEBUG(0,("unknown switch in SAMLOGON %d\n",
1521 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]);
1522 DEBUG(1,("userNAME %s [%s]\n", foo, username));
1523 DEBUG(1,("SMLOG %d\n", __LINE__));
1525 qSIVAL(0x16a4b4); /* magic buffer pointer ? */
1526 makecred(cnum, clnttime+1, q);
1527 dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1;
1529 qSIVAL(0); /* timestamp. client doesn't care */
1530 qSSVAL(3); /* switch value 3. May be others? */
1531 qSSVAL(0); /* undocumented */
1532 DEBUG(1,("SMLOG %d\n", __LINE__));
1534 memset(rc4key, 0, sizeof rc4key);
1535 SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]);
1536 SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]);
1537 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]);
1538 DEBUG(1,("rc4ntowf %s\n", foo));
1539 arcfour_init(&c, rc4key, sizeof rc4key);
1540 arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass);
1541 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]);
1542 DEBUG(1,("ntowf %s\n", foo));
1544 if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) {
1545 qSIVAL(0); /* no buffer */
1546 qSCVAL(1); /* Authoratitive. Change if passthrough? */
1547 qSCVAL(0); /* pad for above boolean */
1548 qSSVAL(0); /* pad for above boolean */
1550 endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len);
1554 qSIVAL(2); /* another magic bufptr? */
1555 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo));
1556 qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]);
1557 qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]);
1558 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1]));
1559 qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]);
1560 qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]);
1561 qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]);
1562 qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]);
1563 DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename));
1564 qunihdr(userinfo->effectivename);
1565 qunihdr(userinfo->fullname);
1566 DEBUG(1,("SMLOG %d\n", __LINE__));
1567 qunihdr(userinfo->logonscript);
1568 qunihdr(userinfo->profilepath);
1569 qunihdr(userinfo->homedirectory);
1570 qunihdr(userinfo->homedirectorydrive);
1571 DEBUG(1,("SMLOG %d\n", __LINE__));
1572 qSSVAL(userinfo->logoncount);
1573 qSSVAL(userinfo->badpwcount);
1574 qSIVAL(userinfo->uid);
1575 qSIVAL(userinfo->gid);
1576 DEBUG(1,("SMLOG %d\n", __LINE__));
1577 qSIVAL(userinfo->ngroups);
1578 qSIVAL(8); /* ptr to groups */
1579 qSIVAL(userinfo->userflags);
1580 DEBUG(1,("SMLOG %d\n", __LINE__));
1581 qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */
1582 qunihdr(userinfo->logonserver);
1583 qunihdr(userinfo->logondomain);
1584 DEBUG(1,("SMLOG %d\n", __LINE__));
1585 qSIVAL(2); /* logon domain id ptr */
1586 DEBUG(1,("SMLOG %d\n", __LINE__));
1587 memset(q,0,40); q += 40; /* expansion room */
1588 DEBUG(1,("SMLOG %d\n", __LINE__));
1589 qSIVAL(userinfo->nsids);
1590 DEBUG(1,("SMLOG %d\n", __LINE__));
1591 qSIVAL(0); /* ptr to sids and values */
1592 DEBUG(1,("SMLOG %d\n", __LINE__));
1593 qunistr(userinfo->effectivename);
1594 DEBUG(1,("SMLOG %d\n", __LINE__));
1595 qunistr(userinfo->fullname);
1596 DEBUG(1,("SMLOG %d\n", __LINE__));
1597 qunistr(userinfo->logonscript);
1598 DEBUG(1,("SMLOG %d\n", __LINE__));
1599 qunistr(userinfo->profilepath);
1600 qunistr(userinfo->homedirectory);
1601 qunistr(userinfo->homedirectorydrive);
1602 DEBUG(1,("SMLOG %d\n", __LINE__));
1603 qSIVAL(userinfo->ngroups);
1604 for (i = 0; i < userinfo->ngroups; i++)
1606 qSIVAL(userinfo->groups[i].gid);
1607 qSIVAL(userinfo->groups[i].attr);
1609 qunistr(userinfo->logonserver);
1610 qunistr(userinfo->logondomain);
1611 for (i = 0; i < userinfo->nsids; i++)
1613 /* put the extra sids: PAXX: TODO */
1615 /* Assumption. This is the only domain, sending our SID */
1616 /* PAXX: may want to do passthrough later */
1617 strcpy(domsid,lp_domainsid());
1618 DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid));
1619 /* assume, but should check, that domsid starts "S-" */
1620 p = strtok(domsid+2,"-");
1622 DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision));
1623 identauth = atoi(strtok(0,"-"));
1624 DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth));
1626 while (p = strtok(0, "-"))
1627 subauths[numsubauths++] = atoi(p);
1628 qSIVAL(numsubauths);
1630 qSCVAL(numsubauths);
1631 qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */
1632 qRSIVAL(identauth); /* next 4 bytes */
1633 DEBUG(1,("SMLOG %d\n", __LINE__));
1634 for (i = 0; i < numsubauths; i++)
1636 qSIVAL(subauths[i]);
1638 qSCVAL(1); /* Authoratitive. Change if passthrough? */
1639 qSCVAL(0); /* pad for above boolean */
1640 qSSVAL(0); /* pad for above boolean */
1642 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1646 BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
1647 int mdrcnt,int mprcnt,
1648 char **rdata,char **rparam,
1649 int *rdata_len,int *rparam_len)
1655 DEBUG(5,("api_netlogrpcTNP data:%x\n", data));
1657 if (data == NULL) return False;
1659 opnum = SVAL(data,22);
1660 pkttype = CVAL(data, 2);
1662 if (pkttype == 0x0b) /* RPC BIND */
1664 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1665 LsarpcTNP1(data,rdata,rdata_len);
1669 DEBUG(4,("netlogon TransactNamedPipe op %x\n", opnum));
1671 if ((vuser = get_valid_user_struct(uid)) == NULL) return False;
1673 DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
1674 #if defined(NETGROUP) && defined(AUTOMOUNT)
1675 DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
1682 DEBUG(3,("LSA_REQCHAL\n"));
1683 api_lsa_req_chal(vuser, param, data, rdata, rdata_len);
1689 DEBUG(3,("LSA_AUTH2\n"));
1690 api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
1696 DEBUG(3,("LSA_SRVPWSET\n"));
1697 api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
1703 DEBUG(3,("LSA_SAMLOGON\n"));
1704 api_lsa_sam_logon(vuser, param, data, rdata, rdata_len);
1710 DEBUG(3,("LSA_SAMLOGOFF\n"));
1711 api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len);
1717 DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
1725 #endif /* NTDOMAIN */