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) - 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);
513 /* store the response in the SMB stream */
514 q = lsa_io_r_open_pol(False, &r_o, q, base, 4);
516 /* return length of SMB data stored */
520 static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate)
522 hdr->uni_max_len = max_len;
523 hdr->uni_str_len = len;
524 hdr->undoc = terminate;
527 static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate)
529 make_uni_hdr(&(hdr->unihdr), max_len, len, terminate);
530 hdr->undoc_buffer = len > 0 ? 1 : 0;
533 static void make_unistr(UNISTR *str, char *buf)
535 /* store the string (null-terminated copy) */
536 PutUniCode((char *)(str->buffer), buf);
539 static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate)
541 /* set up string lengths. add one if string is not null-terminated */
542 str->uni_max_len = len + (terminate != 0 ? 1 : 0);
544 str->uni_str_len = len;
546 /* store the string (null-terminated copy) */
547 PutUniCode((char *)str->buffer, buf);
549 /* overwrite the last character: some strings are terminated with 4 not 0 */
550 str->buffer[len] = (uint16)terminate;
553 static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid)
561 static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str)
563 int len_sid_str = strlen(sid_str);
567 make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0);
568 make_unistr (&(sid2->str), sid_str);
571 static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid)
573 int domlen = strlen(dom_name);
575 d_q->uni_dom_max_len = domlen * 2;
577 d_q->uni_dom_str_len = domlen * 2;
579 d_q->buffer_dom_name = 0; /* domain buffer pointer */
580 d_q->buffer_dom_sid = 0; /* domain sid pointer */
582 /* NOT null-terminated: 4-terminated instead! */
583 make_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4);
585 make_dom_sid(&(d_q->dom_sid), dom_sid);
588 static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base,
589 char *dom_name, char *dom_sid)
592 LSA_R_QUERY_INFO r_q;
594 /* set up the LSA QUERY INFO response */
596 r_q.undoc_buffer = 1; /* not null */
597 r_q.info_class = q_q->info_class;
599 make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
603 /* store the response in the SMB stream */
604 q = lsa_io_r_query(False, &r_q, q, base, 4);
606 /* return length of SMB data stored */
610 /* pretty much hard-coded choice of "other" sids, unfortunately... */
611 static void make_dom_ref(DOM_R_REF *ref,
612 char *dom_name, char *dom_sid,
613 char *other_sid1, char *other_sid2, char *other_sid3)
615 int len_dom_name = strlen(dom_name);
616 int len_other_sid1 = strlen(other_sid1);
617 int len_other_sid2 = strlen(other_sid2);
618 int len_other_sid3 = strlen(other_sid3);
620 ref->undoc_buffer = 1;
621 ref->num_ref_doms_1 = 4;
622 ref->buffer_dom_name = 1;
623 ref->max_entries = 32;
624 ref->num_ref_doms_2 = 4;
626 make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0);
627 make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0);
628 make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0);
629 make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0);
631 if (dom_name != NULL)
633 make_unistr(&(ref->uni_dom_name), dom_name);
636 make_dom_sid(&(ref->ref_dom[0]), dom_sid );
637 make_dom_sid(&(ref->ref_dom[1]), other_sid1);
638 make_dom_sid(&(ref->ref_dom[2]), other_sid2);
639 make_dom_sid(&(ref->ref_dom[3]), other_sid3);
642 static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l,
643 int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
644 char *dom_name, char *dom_sid,
645 char *other_sid1, char *other_sid2, char *other_sid3)
649 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
650 other_sid1, other_sid2, other_sid3);
652 r_l->num_entries = num_entries;
653 r_l->undoc_buffer = 1;
654 r_l->num_entries2 = num_entries;
656 for (i = 0; i < num_entries; i++)
658 make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]);
661 r_l->num_entries3 = num_entries;
664 static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
665 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
666 char *dom_name, char *dom_sid,
667 char *other_sid1, char *other_sid2, char *other_sid3)
671 make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
672 other_sid1, other_sid2, other_sid3);
674 r_l->num_entries = num_entries;
675 r_l->undoc_buffer = 1;
676 r_l->num_entries2 = num_entries;
678 for (i = 0; i < num_entries; i++)
680 make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]);
683 r_l->num_entries3 = num_entries;
686 static int lsa_reply_lookup_sids(char *q, char *base,
687 int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
688 char *dom_name, char *dom_sid,
689 char *other_sid1, char *other_sid2, char *other_sid3)
692 LSA_R_LOOKUP_SIDS r_l;
694 /* set up the LSA Lookup SIDs response */
695 make_reply_lookup_sids(&r_l, num_entries, dom_sids,
696 dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
699 /* store the response in the SMB stream */
700 q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4);
702 /* return length of SMB data stored */
706 static int lsa_reply_lookup_rids(char *q, char *base,
707 int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
708 char *dom_name, char *dom_sid,
709 char *other_sid1, char *other_sid2, char *other_sid3)
712 LSA_R_LOOKUP_RIDS r_l;
714 /* set up the LSA Lookup RIDs response */
715 make_reply_lookup_rids(&r_l, num_entries, dom_rids,
716 dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
719 /* store the response in the SMB stream */
720 q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4);
722 /* return length of SMB data stored */
726 static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c,
727 DOM_CHAL *srv_chal, int status)
729 memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(r_c->srv_chal.data));
730 r_c->status = status;
733 static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
739 /* set up the LSA REQUEST CHALLENGE response */
741 make_lsa_r_req_chal(&r_c, srv_chal, 0);
743 /* store the response in the SMB stream */
744 q = lsa_io_r_req_chal(False, &r_c, q, base, 4);
746 /* return length of SMB data stored */
750 static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
751 DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
753 memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
754 memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
755 r_a->status = status;
758 static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
759 DOM_CHAL *resp_cred, int status)
764 /* set up the LSA AUTH 2 response */
766 make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
768 /* store the response in the SMB stream */
769 q = lsa_io_r_auth_2(False, &r_a, q, base, 4);
771 /* return length of SMB data stored */
775 static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a,
776 DOM_CRED *srv_cred, int status)
778 memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred));
779 r_a->status = status;
782 static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
783 DOM_CRED *srv_cred, int status)
788 /* set up the LSA Server Password Set response */
789 make_lsa_r_srv_pwset(&r_s, srv_cred, status);
791 /* store the response in the SMB stream */
792 q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4);
794 /* return length of SMB data stored */
798 static void make_lsa_user_info(LSA_USER_INFO *usr,
802 NTTIME *kickoff_time,
803 NTTIME *pass_last_set_time,
804 NTTIME *pass_can_change_time,
805 NTTIME *pass_must_change_time,
829 char *other_sids) /* space-delimited set of SIDs */
831 /* only cope with one "other" sid, right now. */
832 /* need to count the number of space-delimited sids */
834 int num_other_sids = other_sids != NULL ? 1 : 0;
836 int len_user_name = strlen(user_name );
837 int len_full_name = strlen(full_name );
838 int len_logon_script = strlen(logon_script);
839 int len_profile_path = strlen(profile_path);
840 int len_home_dir = strlen(home_dir );
841 int len_dir_drive = strlen(dir_drive );
843 int len_logon_srv = strlen(logon_srv);
844 int len_logon_dom = strlen(logon_dom);
846 usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */
848 usr->logon_time = *logon_time;
849 usr->logoff_time = *logoff_time;
850 usr->kickoff_time = *kickoff_time;
851 usr->pass_last_set_time = *pass_last_set_time;
852 usr->pass_can_change_time = *pass_can_change_time;
853 usr->pass_must_change_time = *pass_must_change_time;
855 make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4);
856 make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4);
857 make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
858 make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
859 make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4);
860 make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4);
862 usr->logon_count = logon_count;
863 usr->bad_pw_count = bad_pw_count;
865 usr->user_id = user_id;
866 usr->group_id = group_id;
867 usr->num_groups = num_groups;
868 usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */
869 usr->user_flgs = user_flgs;
871 if (sess_key != NULL)
873 memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key));
877 bzero(usr->sess_key, sizeof(usr->sess_key));
880 make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
881 make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
883 usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
885 bzero(usr->padding, sizeof(usr->padding));
887 usr->num_other_sids = num_other_sids;
888 usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
890 make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0);
891 make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0);
892 make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0);
893 make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0);
894 make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0);
895 make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0);
897 usr->num_groups2 = num_groups;
898 for (i = 0; i < num_groups; i++)
900 usr->gids[i] = gids[i];
903 make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0);
904 make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0);
906 make_dom_sid(&(usr->dom_sid), dom_sid);
907 make_dom_sid(&(usr->other_sids[0]), other_sids);
911 static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
912 DOM_CRED *srv_cred, LSA_USER_INFO *user_info)
917 /* XXXX maybe we want to say 'no', reject the client's credentials */
918 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
919 memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
921 /* store the user information, if there is any. */
922 r_s.user = user_info;
923 r_s.buffer_user = user_info != NULL ? 1 : 0;
924 r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER);
926 /* store the response in the SMB stream */
927 q = lsa_io_r_sam_logon(False, &r_s, q, base, 4);
929 /* return length of SMB data stored */
934 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);
950 /* return length of SMB data stored */
955 static void api_lsa_open_policy( char *param, char *data,
956 char **rdata, int *rdata_len )
960 /* we might actually want to decode the query, but it's not necessary */
961 /* lsa_io_q_open_policy(...); */
963 /* return a 20 byte policy handle */
964 reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18);
966 /* construct header, now that we know the reply length */
967 make_rpc_reply(data, *rdata, reply_len);
968 *rdata_len = reply_len + 0x18;
971 static void api_lsa_query_info( char *param, char *data,
972 char **rdata, int *rdata_len )
976 LSA_Q_QUERY_INFO q_i;
980 /* grab the info class and policy handle */
981 lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4);
983 pstrcpy(dom_name, lp_workgroup());
984 pstrcpy(dom_sid , lp_domainsid());
986 /* construct reply. return status is always 0x0 */
987 reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18,
990 /* construct header, now that we know the reply length */
991 make_rpc_reply(data, *rdata, reply_len);
992 *rdata_len = reply_len + 0x18;
995 static void api_lsa_lookup_sids( char *param, char *data,
996 char **rdata, int *rdata_len )
1001 LSA_Q_LOOKUP_SIDS q_l;
1004 fstring dom_sids[MAX_LOOKUP_SIDS];
1006 /* grab the info class and policy handle */
1007 lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4);
1009 pstrcpy(dom_name, lp_workgroup());
1010 pstrcpy(dom_sid , lp_domainsid());
1012 /* convert received SIDs to strings, so we can do them. */
1013 for (i = 0; i < q_l.num_entries; i++)
1015 fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i])));
1018 /* construct reply. return status is always 0x0 */
1019 reply_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata + 0x18,
1020 q_l.num_entries, dom_sids, /* text-converted SIDs */
1021 dom_name, dom_sid, /* domain name, domain SID */
1022 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1024 /* construct header, now that we know the reply length */
1025 make_rpc_reply(data, *rdata, reply_len);
1026 *rdata_len = reply_len + 0x18;
1029 static void api_lsa_lookup_names( char *param, char *data,
1030 char **rdata, int *rdata_len )
1035 LSA_Q_LOOKUP_RIDS q_l;
1038 uint32 dom_rids[MAX_LOOKUP_SIDS];
1040 /* grab the info class and policy handle */
1041 lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4);
1043 pstrcpy(dom_name, lp_workgroup());
1044 pstrcpy(dom_sid , lp_domainsid());
1046 /* convert received RIDs to strings, so we can do them. */
1047 for (i = 0; i < q_l.num_entries; i++)
1049 char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
1050 dom_rids[i] = name_to_rid(user_name);
1053 /* construct reply. return status is always 0x0 */
1054 reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18,
1055 q_l.num_entries, dom_rids, /* text-converted SIDs */
1056 dom_name, dom_sid, /* domain name, domain SID */
1057 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1059 /* construct header, now that we know the reply length */
1060 make_rpc_reply(data, *rdata, reply_len);
1061 *rdata_len = reply_len + 0x18;
1064 BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
1065 int mdrcnt,int mprcnt,
1066 char **rdata,char **rparam,
1067 int *rdata_len,int *rparam_len)
1069 uint16 opnum = SVAL(data,22);
1071 int pkttype = CVAL(data, 2);
1072 if (pkttype == 0x0b) /* RPC BIND */
1074 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1075 LsarpcTNP1(data,rdata,rdata_len);
1079 DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum));
1082 case LSA_OPENPOLICY:
1084 DEBUG(3,("LSA_OPENPOLICY\n"));
1085 api_lsa_open_policy(param, data, rdata, rdata_len);
1089 case LSA_QUERYINFOPOLICY:
1091 DEBUG(3,("LSA_QUERYINFOPOLICY\n"));
1093 api_lsa_query_info(param, data, rdata, rdata_len);
1097 case LSA_ENUMTRUSTDOM:
1099 char *q = *rdata + 0x18;
1101 DEBUG(3,("LSA_ENUMTRUSTDOM\n"));
1103 initrpcreply(data, *rdata);
1105 SIVAL(q, 0, 0); /* enumeration context */
1106 SIVAL(q, 0, 4); /* entries read */
1107 SIVAL(q, 0, 8); /* trust information */
1109 endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len);
1116 char *q = *rdata + 0x18;
1118 DEBUG(3,("LSA_CLOSE\n"));
1120 initrpcreply(data, *rdata);
1128 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1133 case LSA_OPENSECRET:
1135 char *q = *rdata + 0x18;
1136 DEBUG(3,("LSA_OPENSECRET\n"));
1138 initrpcreply(data, *rdata);
1146 endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len);
1151 case LSA_LOOKUPSIDS:
1153 DEBUG(3,("LSA_OPENSECRET\n"));
1154 api_lsa_lookup_sids(param, data, rdata, rdata_len);
1158 case LSA_LOOKUPNAMES:
1160 DEBUG(3,("LSA_LOOKUPNAMES\n"));
1161 api_lsa_lookup_names(param, data, rdata, rdata_len);
1167 DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum));
1174 static BOOL update_dcinfo(struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct)
1176 struct smb_passwd *smb_pass = get_smbpwnam(mach_acct);
1179 if (smb_pass != NULL)
1181 memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw));
1185 /* No such machine account. Should error out here, but we'll
1186 print and carry on */
1187 DEBUG(1,("No account in domain for %s\n", mach_acct));
1193 for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]);
1194 DEBUG(4,("pass %s %s\n", mach_acct, foo));
1197 /* from client / server challenges and md4 password, generate sess key */
1198 cred_session_key(&(dc->clnt_chal), &(dc->srv_chal),
1199 dc->md4pw, dc->sess_key);
1201 /* copy the client credentials for later use */
1202 memcpy(dc->srv_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
1203 memcpy(dc->srv_cred.data, clnt_chal->data, sizeof(clnt_chal->data));
1205 /* create a server challenge for the client */
1206 /* PAXX: set these to random values. */
1207 /* lkcl: paul, you mentioned that it doesn't really matter much */
1208 for (i = 0; i < 8; i++)
1210 dc->srv_chal.data[i] = 0xA5;
1216 static void api_lsa_req_chal( user_struct *vuser,
1217 char *param, char *data,
1218 char **rdata, int *rdata_len )
1226 /* grab the challenge... */
1227 lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4);
1229 fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer));
1231 strcat(mach_acct, "$");
1233 update_dcinfo(&(vuser->dc), &(q_r.clnt_chal), mach_acct);
1235 /* construct reply. return status is always 0x0 */
1236 reply_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata + 0x18,
1237 &(vuser->dc.srv_chal));
1239 /* construct header, now that we know the reply length */
1240 reply_len += make_rpc_reply(data, *rdata, reply_len);
1242 *rdata_len = reply_len;
1245 static void api_lsa_auth_2( user_struct *vuser,
1246 char *param, char *data,
1247 char **rdata, int *rdata_len )
1257 /* grab the challenge... */
1258 lsa_io_q_auth_2(True, &q_a, data + 0x18, data + 0x18, 4);
1260 /* check that the client credentials are valid */
1261 cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
1262 &(vuser->dc.srv_cred), srv_time);
1264 /* create server credentials for inclusion in the reply */
1265 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), srv_time, &srv_chal);
1267 /* construct reply. */
1268 reply_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata + 0x18,
1271 /* construct header, now that we know the reply length */
1272 reply_len += make_rpc_reply(data, *rdata, reply_len);
1274 *rdata_len = reply_len;
1278 static BOOL deal_with_credentials(user_struct *vuser,
1279 DOM_CRED *clnt_cred, DOM_CRED *srv_cred)
1281 UTIME new_clnt_time;
1283 /* doesn't matter that server time is 0 */
1284 srv_cred->timestamp.time = 0;
1286 /* check that the client credentials are valid */
1287 if (cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key,
1288 &(vuser->dc.srv_cred), clnt_cred->timestamp))
1293 /* increment client time by one second */
1294 new_clnt_time.time = clnt_cred->timestamp.time + 1;
1296 /* create server credentials for inclusion in the reply */
1297 cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time,
1298 &(srv_cred->challenge));
1300 /* update the client and server credentials, for use next time... */
1301 *(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time );
1306 static void api_lsa_srv_pwset( user_struct *vuser,
1307 char *param, char *data,
1308 char **rdata, int *rdata_len )
1311 LSA_Q_SRV_PWSET q_a;
1315 /* grab the challenge and encrypted password ... */
1316 lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4);
1318 /* checks and updates credentials. creates reply credentials */
1319 deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred);
1321 /* construct reply. always indicate failure. nt keeps going... */
1322 reply_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata + 0x18,
1324 NT_STATUS_WRONG_PASSWORD|0xC000000);
1326 /* construct header, now that we know the reply length */
1327 reply_len += make_rpc_reply(data, *rdata, reply_len);
1329 *rdata_len = reply_len;
1333 static void api_lsa_sam_logoff( user_struct *vuser,
1334 char *param, char *data,
1335 char **rdata, int *rdata_len )
1338 LSA_Q_SAM_LOGOFF q_l;
1342 /* grab the challenge... */
1343 lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4);
1345 /* checks and updates credentials. creates reply credentials */
1346 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred);
1348 /* construct reply. always indicate success */
1349 reply_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata + 0x18,
1353 /* construct header, now that we know the reply length */
1354 reply_len += make_rpc_reply(data, *rdata, reply_len);
1356 *rdata_len = reply_len;
1360 static void api_lsa_sam_logon( user_struct *vuser,
1361 char *param, char *data,
1362 char **rdata, int *rdata_len )
1365 LSA_Q_SAM_LOGON q_l;
1366 LSA_USER_INFO usr_info;
1367 LSA_USER_INFO *p_usr_info = NULL;
1371 lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4);
1373 /* checks and updates credentials. creates reply credentials */
1374 deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds);
1379 pstring logon_script;
1380 pstring profile_path;
1384 pstring my_workgroup;
1387 extern pstring myname;
1389 dummy_time.low = 0xffffffff;
1390 dummy_time.high = 0x7fffffff;
1392 get_myname(myname, NULL);
1394 pstrcpy(logon_script, lp_logon_script());
1395 pstrcpy(profile_path, lp_logon_path ());
1396 pstrcpy(dom_sid , lp_domainsid ());
1397 pstrcpy(my_workgroup, lp_workgroup ());
1399 pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer));
1400 pstrcpy(my_name , myname );
1403 pstrcpy(home_drive , "a:" );
1405 #if (defined(NETGROUP) && defined(AUTOMOUNT))
1406 pstrcpy(home_dir , vuser->home_share);
1408 pstrcpy(home_dir , "\\\\%L\\%U");
1409 standard_sub_basic(home_dir);
1412 p_usr_info = &usr_info;
1414 make_lsa_user_info(p_usr_info,
1416 &dummy_time, /* logon_time */
1417 &dummy_time, /* logoff_time */
1418 &dummy_time, /* kickoff_time */
1419 &dummy_time, /* pass_last_set_time */
1420 &dummy_time, /* pass_can_change_time */
1421 &dummy_time, /* pass_must_change_time */
1423 username, /* user_name */
1424 vuser->real_name, /* full_name */
1425 logon_script, /* logon_script */
1426 profile_path, /* profile_path */
1427 home_dir, /* home_dir */
1428 home_drive, /* dir_drive */
1430 0, /* logon_count */
1431 0, /* bad_pw_count */
1433 vuser->uid, /* uint32 user_id */
1434 vuser->gid, /* uint32 group_id */
1435 0, /* uint32 num_groups */
1436 NULL, /* DOM_GID *gids */
1437 0x20, /* uint32 user_flgs */
1439 NULL, /* char sess_key[16] */
1441 my_name, /* char *logon_srv */
1442 my_workgroup, /* char *logon_dom */
1444 dom_sid, /* char *dom_sid */
1445 NULL); /* char *other_sids */
1448 reply_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata + 0x18,
1449 &srv_creds, p_usr_info);
1451 /* construct header, now that we know the reply length */
1452 reply_len += make_rpc_reply(data, *rdata, reply_len);
1454 *rdata_len = reply_len;
1460 DEBUG(1,("LSASAMLOGON\n"));
1461 dump_data(1,data,128);
1464 DEBUG(1,("SMLOG %d\n", __LINE__));
1465 q = skip_unicode_string(logonsrv,1)+16;
1466 q = align4(q, data);
1468 q = skip_unicode_string(unicomp,1)+4;
1469 DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n",
1470 __LINE__, unistr(logonsrv), unistr(unicomp)));
1471 q = align4(q, data);
1473 DEBUG(1,("SMLOG %d\n", __LINE__));
1475 DEBUG(1,("SMLOG %d\n", __LINE__));
1477 checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
1479 rtncred[0] = qIVAL; /* all these are ignored */
1480 DEBUG(1,("SMLOG %d\n", __LINE__));
1484 DEBUG(1,("SMLOG %d\n", __LINE__));
1492 dommaxlen = qSVAL; q += 4;
1493 paramcontrol = qIVAL;
1494 logonid[0] = qIVAL; /* low part */
1495 logonid[1] = qIVAL; /* high part */
1497 usernamelen = qSVAL;
1499 DEBUG(1,("SMLOG %d\n", __LINE__));
1500 usernamemaxlen = qSVAL; q += 4;
1502 DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n",
1503 usernamelen, usernamemaxlen, dommaxlen));
1508 wsmaxlen = qSVAL; q += 4;
1509 rc4lmowfpass = q; q += 16;
1510 rc4ntowfpass = q; q += 16;
1512 q += 12; domain = q; q += dommaxlen + 12;
1513 q = align4(q, data);
1514 username = q; q += usernamemaxlen + 12;
1515 q = align4(q, data);
1517 DEBUG(1,("domain=%s username=%s ws=%s\n",
1518 unistr(domain), unistr(username),
1522 DEBUG(0,("unknown switch in SAMLOGON %d\n",
1525 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]);
1526 DEBUG(1,("userNAME %s [%s]\n", foo, username));
1527 DEBUG(1,("SMLOG %d\n", __LINE__));
1529 qSIVAL(0x16a4b4); /* magic buffer pointer ? */
1530 makecred(cnum, clnttime+1, q);
1531 dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1;
1533 qSIVAL(0); /* timestamp. client doesn't care */
1534 qSSVAL(3); /* switch value 3. May be others? */
1535 qSSVAL(0); /* undocumented */
1536 DEBUG(1,("SMLOG %d\n", __LINE__));
1538 memset(rc4key, 0, sizeof rc4key);
1539 SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]);
1540 SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]);
1541 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]);
1542 DEBUG(1,("rc4ntowf %s\n", foo));
1543 arcfour_init(&c, rc4key, sizeof rc4key);
1544 arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass);
1545 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]);
1546 DEBUG(1,("ntowf %s\n", foo));
1548 if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) {
1549 qSIVAL(0); /* no buffer */
1550 qSCVAL(1); /* Authoratitive. Change if passthrough? */
1551 qSCVAL(0); /* pad for above boolean */
1552 qSSVAL(0); /* pad for above boolean */
1554 endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len);
1558 qSIVAL(2); /* another magic bufptr? */
1559 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo));
1560 qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]);
1561 qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]);
1562 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1]));
1563 qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]);
1564 qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]);
1565 qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]);
1566 qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]);
1567 DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename));
1568 qunihdr(userinfo->effectivename);
1569 qunihdr(userinfo->fullname);
1570 DEBUG(1,("SMLOG %d\n", __LINE__));
1571 qunihdr(userinfo->logonscript);
1572 qunihdr(userinfo->profilepath);
1573 qunihdr(userinfo->homedirectory);
1574 qunihdr(userinfo->homedirectorydrive);
1575 DEBUG(1,("SMLOG %d\n", __LINE__));
1576 qSSVAL(userinfo->logoncount);
1577 qSSVAL(userinfo->badpwcount);
1578 qSIVAL(userinfo->uid);
1579 qSIVAL(userinfo->gid);
1580 DEBUG(1,("SMLOG %d\n", __LINE__));
1581 qSIVAL(userinfo->ngroups);
1582 qSIVAL(8); /* ptr to groups */
1583 qSIVAL(userinfo->userflags);
1584 DEBUG(1,("SMLOG %d\n", __LINE__));
1585 qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */
1586 qunihdr(userinfo->logonserver);
1587 qunihdr(userinfo->logondomain);
1588 DEBUG(1,("SMLOG %d\n", __LINE__));
1589 qSIVAL(2); /* logon domain id ptr */
1590 DEBUG(1,("SMLOG %d\n", __LINE__));
1591 memset(q,0,40); q += 40; /* expansion room */
1592 DEBUG(1,("SMLOG %d\n", __LINE__));
1593 qSIVAL(userinfo->nsids);
1594 DEBUG(1,("SMLOG %d\n", __LINE__));
1595 qSIVAL(0); /* ptr to sids and values */
1596 DEBUG(1,("SMLOG %d\n", __LINE__));
1597 qunistr(userinfo->effectivename);
1598 DEBUG(1,("SMLOG %d\n", __LINE__));
1599 qunistr(userinfo->fullname);
1600 DEBUG(1,("SMLOG %d\n", __LINE__));
1601 qunistr(userinfo->logonscript);
1602 DEBUG(1,("SMLOG %d\n", __LINE__));
1603 qunistr(userinfo->profilepath);
1604 qunistr(userinfo->homedirectory);
1605 qunistr(userinfo->homedirectorydrive);
1606 DEBUG(1,("SMLOG %d\n", __LINE__));
1607 qSIVAL(userinfo->ngroups);
1608 for (i = 0; i < userinfo->ngroups; i++)
1610 qSIVAL(userinfo->groups[i].gid);
1611 qSIVAL(userinfo->groups[i].attr);
1613 qunistr(userinfo->logonserver);
1614 qunistr(userinfo->logondomain);
1615 for (i = 0; i < userinfo->nsids; i++)
1617 /* put the extra sids: PAXX: TODO */
1619 /* Assumption. This is the only domain, sending our SID */
1620 /* PAXX: may want to do passthrough later */
1621 strcpy(domsid,lp_domainsid());
1622 DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid));
1623 /* assume, but should check, that domsid starts "S-" */
1624 p = strtok(domsid+2,"-");
1626 DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision));
1627 identauth = atoi(strtok(0,"-"));
1628 DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth));
1630 while (p = strtok(0, "-"))
1631 subauths[numsubauths++] = atoi(p);
1632 qSIVAL(numsubauths);
1634 qSCVAL(numsubauths);
1635 qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */
1636 qRSIVAL(identauth); /* next 4 bytes */
1637 DEBUG(1,("SMLOG %d\n", __LINE__));
1638 for (i = 0; i < numsubauths; i++)
1640 qSIVAL(subauths[i]);
1642 qSCVAL(1); /* Authoratitive. Change if passthrough? */
1643 qSCVAL(0); /* pad for above boolean */
1644 qSSVAL(0); /* pad for above boolean */
1646 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1650 BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
1651 int mdrcnt,int mprcnt,
1652 char **rdata,char **rparam,
1653 int *rdata_len,int *rparam_len)
1655 uint16 opnum = SVAL(data,22);
1656 int pkttype = CVAL(data, 2);
1658 user_struct *vuser = get_valid_user_struct(uid);
1660 if (pkttype == 0x0b) /* RPC BIND */
1662 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1663 LsarpcTNP1(data,rdata,rdata_len);
1667 DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum));
1669 if (vuser == NULL) return False;
1671 DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
1672 #if defined(NETGROUP) && defined(AUTOMOUNT)
1673 DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
1680 DEBUG(3,("LSA_REQCHAL\n"));
1681 api_lsa_req_chal(vuser, param, data, rdata, rdata_len);
1687 DEBUG(3,("LSA_AUTH2\n"));
1688 api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
1694 DEBUG(3,("LSA_SRVPWSET\n"));
1695 api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
1701 DEBUG(3,("LSA_SAMLOGON\n"));
1702 api_lsa_sam_logon(vuser, param, data, rdata, rdata_len);
1708 DEBUG(3,("LSA_SAMLOGOFF\n"));
1709 api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len);
1715 DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
1723 #endif /* NTDOMAIN */