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_chal(DOM_CHAL *cred, char resp_cred[8])
752 memcpy(cred->data, resp_cred, sizeof(cred->data));
755 static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
756 char resp_cred[8], NEG_FLAGS *flgs, int status)
758 make_lsa_chal(&(r_a->srv_chal), resp_cred);
759 memcpy(&(r_a->srv_flgs), flgs, sizeof(r_a->srv_flgs));
760 r_a->status = status;
763 static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
764 char resp_cred[8], int status)
769 /* set up the LSA AUTH 2 response */
771 make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
773 /* store the response in the SMB stream */
774 q = lsa_io_r_auth_2(False, &r_a, q, base, 4);
776 /* return length of SMB data stored */
780 static void make_lsa_dom_chal(DOM_CRED *cred, char srv_chal[8], UTIME srv_time)
782 make_lsa_chal(&(cred->challenge), srv_chal);
783 cred->timestamp = srv_time;
787 static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a,
788 char srv_chal[8], UTIME srv_time, int status)
790 make_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time);
791 r_a->status = status;
794 static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
795 char srv_cred[8], UTIME srv_time,
801 /* set up the LSA Server Password Set response */
802 make_lsa_r_srv_pwset(&r_s, srv_cred, srv_time, status);
804 /* store the response in the SMB stream */
805 q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4);
807 /* return length of SMB data stored */
811 static void make_lsa_user_info(LSA_USER_INFO *usr,
815 NTTIME *kickoff_time,
816 NTTIME *pass_last_set_time,
817 NTTIME *pass_can_change_time,
818 NTTIME *pass_must_change_time,
842 char *other_sids) /* space-delimited set of SIDs */
844 /* only cope with one "other" sid, right now. */
845 /* need to count the number of space-delimited sids */
847 int num_other_sids = other_sids != NULL ? 1 : 0;
849 int len_user_name = strlen(user_name );
850 int len_full_name = strlen(full_name );
851 int len_logon_script = strlen(logon_script);
852 int len_profile_path = strlen(profile_path);
853 int len_home_dir = strlen(home_dir );
854 int len_dir_drive = strlen(dir_drive );
856 int len_logon_srv = strlen(logon_srv);
857 int len_logon_dom = strlen(logon_dom);
859 usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */
861 usr->logon_time = *logon_time;
862 usr->logoff_time = *logoff_time;
863 usr->kickoff_time = *kickoff_time;
864 usr->pass_last_set_time = *pass_last_set_time;
865 usr->pass_can_change_time = *pass_can_change_time;
866 usr->pass_must_change_time = *pass_must_change_time;
868 make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4);
869 make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4);
870 make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
871 make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
872 make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4);
873 make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4);
875 usr->logon_count = logon_count;
876 usr->bad_pw_count = bad_pw_count;
878 usr->user_id = user_id;
879 usr->group_id = group_id;
880 usr->num_groups = num_groups;
881 usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */
882 usr->user_flgs = user_flgs;
884 if (sess_key != NULL)
886 memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key));
890 bzero(usr->sess_key, sizeof(usr->sess_key));
893 make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
894 make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
896 usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
898 bzero(usr->padding, sizeof(usr->padding));
900 usr->num_other_sids = num_other_sids;
901 usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
903 make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0);
904 make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0);
905 make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0);
906 make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0);
907 make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0);
908 make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0);
910 usr->num_groups2 = num_groups;
911 for (i = 0; i < num_groups; i++)
913 usr->gids[i] = gids[i];
916 make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0);
917 make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0);
919 make_dom_sid(&(usr->dom_sid), dom_sid);
920 make_dom_sid(&(usr->other_sids[0]), other_sids);
924 static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
925 char srv_cred[8], UTIME srv_time,
926 LSA_USER_INFO *user_info)
931 /* XXXX maybe we want to say 'no', reject the client's credentials */
932 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
933 make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time);
935 /* store the user information, if there is any. */
936 r_s.user = user_info;
937 r_s.buffer_user = user_info != NULL ? 1 : 0;
938 r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER);
940 /* store the response in the SMB stream */
941 q = lsa_io_r_sam_logon(False, &r_s, q, base, 4);
943 /* return length of SMB data stored */
948 static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
949 char srv_cred[8], UTIME srv_time,
953 LSA_R_SAM_LOGOFF r_s;
955 /* XXXX maybe we want to say 'no', reject the client's credentials */
956 r_s.buffer_creds = 1; /* yes, we have valid server credentials */
957 make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time);
961 /* store the response in the SMB stream */
962 q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4);
964 /* return length of SMB data stored */
969 static void api_lsa_open_policy( char *param, char *data,
970 char **rdata, int *rdata_len )
974 /* we might actually want to decode the query, but it's not necessary */
975 /* lsa_io_q_open_policy(...); */
977 /* return a 20 byte policy handle */
978 reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18);
980 /* construct header, now that we know the reply length */
981 make_rpc_reply(data, *rdata, reply_len);
982 *rdata_len = reply_len + 0x18;
985 static void api_lsa_query_info( char *param, char *data,
986 char **rdata, int *rdata_len )
990 LSA_Q_QUERY_INFO q_i;
994 /* grab the info class and policy handle */
995 lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4);
997 pstrcpy(dom_name, lp_workgroup());
998 pstrcpy(dom_sid , lp_domainsid());
1000 /* construct reply. return status is always 0x0 */
1001 reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18,
1004 /* construct header, now that we know the reply length */
1005 make_rpc_reply(data, *rdata, reply_len);
1006 *rdata_len = reply_len + 0x18;
1009 static void api_lsa_lookup_sids( char *param, char *data,
1010 char **rdata, int *rdata_len )
1015 LSA_Q_LOOKUP_SIDS q_l;
1018 fstring dom_sids[MAX_LOOKUP_SIDS];
1020 /* grab the info class and policy handle */
1021 lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4);
1023 pstrcpy(dom_name, lp_workgroup());
1024 pstrcpy(dom_sid , lp_domainsid());
1026 /* convert received SIDs to strings, so we can do them. */
1027 for (i = 0; i < q_l.num_entries; i++)
1029 fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i])));
1032 /* construct reply. return status is always 0x0 */
1033 reply_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata + 0x18,
1034 q_l.num_entries, dom_sids, /* text-converted SIDs */
1035 dom_name, dom_sid, /* domain name, domain SID */
1036 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1038 /* construct header, now that we know the reply length */
1039 make_rpc_reply(data, *rdata, reply_len);
1040 *rdata_len = reply_len + 0x18;
1043 static void api_lsa_lookup_names( char *param, char *data,
1044 char **rdata, int *rdata_len )
1049 LSA_Q_LOOKUP_RIDS q_l;
1052 uint32 dom_rids[MAX_LOOKUP_SIDS];
1054 /* grab the info class and policy handle */
1055 lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4);
1057 pstrcpy(dom_name, lp_workgroup());
1058 pstrcpy(dom_sid , lp_domainsid());
1060 /* convert received RIDs to strings, so we can do them. */
1061 for (i = 0; i < q_l.num_entries; i++)
1063 char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
1064 dom_rids[i] = name_to_rid(user_name);
1067 /* construct reply. return status is always 0x0 */
1068 reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18,
1069 q_l.num_entries, dom_rids, /* text-converted SIDs */
1070 dom_name, dom_sid, /* domain name, domain SID */
1071 "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
1073 /* construct header, now that we know the reply length */
1074 make_rpc_reply(data, *rdata, reply_len);
1075 *rdata_len = reply_len + 0x18;
1078 BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
1079 int mdrcnt,int mprcnt,
1080 char **rdata,char **rparam,
1081 int *rdata_len,int *rparam_len)
1083 uint16 opnum = SVAL(data,22);
1085 int pkttype = CVAL(data, 2);
1086 if (pkttype == 0x0b) /* RPC BIND */
1088 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1089 LsarpcTNP1(data,rdata,rdata_len);
1093 DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum));
1096 case LSA_OPENPOLICY:
1098 DEBUG(3,("LSA_OPENPOLICY\n"));
1099 api_lsa_open_policy(param, data, rdata, rdata_len);
1103 case LSA_QUERYINFOPOLICY:
1105 DEBUG(3,("LSA_QUERYINFOPOLICY\n"));
1107 api_lsa_query_info(param, data, rdata, rdata_len);
1111 case LSA_ENUMTRUSTDOM:
1113 char *q = *rdata + 0x18;
1115 DEBUG(3,("LSA_ENUMTRUSTDOM\n"));
1117 initrpcreply(data, *rdata);
1119 SIVAL(q, 0, 0); /* enumeration context */
1120 SIVAL(q, 0, 4); /* entries read */
1121 SIVAL(q, 0, 8); /* trust information */
1123 endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len);
1130 char *q = *rdata + 0x18;
1132 DEBUG(3,("LSA_CLOSE\n"));
1134 initrpcreply(data, *rdata);
1142 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1147 case LSA_OPENSECRET:
1149 char *q = *rdata + 0x18;
1150 DEBUG(3,("LSA_OPENSECRET\n"));
1152 initrpcreply(data, *rdata);
1160 endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len);
1165 case LSA_LOOKUPSIDS:
1167 DEBUG(3,("LSA_OPENSECRET\n"));
1168 api_lsa_lookup_sids(param, data, rdata, rdata_len);
1172 case LSA_LOOKUPNAMES:
1174 DEBUG(3,("LSA_LOOKUPNAMES\n"));
1175 api_lsa_lookup_names(param, data, rdata, rdata_len);
1181 DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum));
1188 static void api_lsa_req_chal( user_struct *vuser,
1189 char *param, char *data,
1190 char **rdata, int *rdata_len )
1198 struct smb_passwd *smb_pass;
1200 /* grab the challenge... */
1201 lsa_io_q_req_chal(True, &q_r, data + 0x18, data + 0x18, 4);
1203 fstrcpy(mach_acct, unistr2(q_r.uni_logon_clnt.buffer));
1205 DEBUG(1,("logonsrv=%s unicomp=%s\n",
1206 unistr2(q_r.uni_logon_srv .buffer),
1209 strcat(mach_acct, "$");
1211 smb_pass = get_smbpwnam(mach_acct);
1212 if (smb_pass != NULL)
1214 memcpy(vuser->dc.md4pw, smb_pass->smb_nt_passwd, sizeof(vuser->dc.md4pw));
1218 /* No such machine account. Should error out here, but we'll
1219 print and carry on */
1220 DEBUG(1,("No account in domain at REQCHAL for %s\n", mach_acct));
1225 for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", vuser->dc.md4pw[i]);
1226 DEBUG(1,("pass %s %s\n", mach_acct, foo));
1229 /* from client / server challenges and md4 password, generate sess key */
1230 cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
1231 vuser->dc.md4pw, vuser->dc.sess_key);
1233 /* copy the client credentials for later use */
1234 memcpy(vuser->dc.srv_chal.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
1235 memcpy(vuser->dc.srv_cred.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
1237 /* create a server challenge for the client */
1238 /* PAXX: set these to random values. */
1239 /* lkcl: paul, you mentioned that it doesn't really matter much */
1240 for (i = 0; i < 8; i++)
1242 vuser->dc.srv_chal.data[i] = 0xA5;
1245 /* construct reply. return status is always 0x0 */
1246 reply_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata + 0x18,
1247 &(vuser->dc.srv_chal));
1249 /* construct header, now that we know the reply length */
1250 reply_len += make_rpc_reply(data, *rdata, reply_len);
1252 *rdata_len = reply_len;
1255 void no_fn(uint uid)
1257 user_struct *vuser = get_valid_user_struct(uid);
1258 DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
1259 #if defined(NETGROUP) && defined(AUTOMOUNT)
1260 DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
1264 #endif /* NTDOMAIN */
1266 #ifdef UNDEFINED_NTDOMAIN
1268 PAXX: Someone fix above.
1269 The above API is indexing RPC calls based on RPC flags and
1270 fragment length. I've decided to do it based on operation number :-)
1273 BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data,
1274 int mdrcnt,int mprcnt,
1275 char **rdata,char **rparam,
1276 int *rdata_len,int *rparam_len)
1285 int subauths[MAXSUBAUTHS];
1286 struct smb_passwd *smb_pass; /* To check if machine account exists */
1290 uint16 revision; /* Domain sid revision */
1296 uint16 secchanneltype;
1307 uint16 paramcontrol;
1310 uint16 usernamemaxlen;
1313 uchar *rc4lmowfpass;
1314 uchar *rc4ntowfpass;
1318 struct uinfo *userinfo;
1321 uchar ntowfpass[16];
1325 uchar *sids[MAXSIDS]; /* for lookup SID */
1328 uchar *names[MAXNAMES];
1330 opnum = SVAL(data,22);
1332 pkttype = CVAL(data, 2);
1333 if (pkttype == 0x0b) /* RPC BIND */
1335 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1336 LsarpcTNP1(data,rdata,rdata_len);
1340 DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum));
1341 initrpcreply(data, *rdata);
1342 DEBUG(4,("netlogon LINE %d\n",__LINE__));
1346 DEBUG(1,("LSAOPENPOLICY\n"));
1347 char *q = *rdata + 0x18;
1348 DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q));
1349 /* return a 20 byte policy handle */
1350 /* here's a pretty handle:- */
1356 DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q));
1357 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len); /* size of data plus return code */
1358 DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q));
1361 case LSAQUERYINFOPOLICY:
1362 DEBUG(1,("LSAQUERYINFOPOLICY\n"));
1363 dump_data(1,data,128);
1364 infoclass = SVAL(data, 44); /* also a policy handle but who cares? */
1366 qRSIVAL(0x00000022); /* undocumented. Usually a buffer pointer whose
1369 domainname = lp_workgroup();
1370 domlen = strlen(domainname);
1371 strcpy(domsid,lp_domainsid());
1372 DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid));
1373 /* assume, but should check, that domsid starts "S-" */
1374 p = strtok(domsid+2,"-");
1376 DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision));
1377 identauth = atoi(strtok(0,"-"));
1378 DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth));
1380 while (p = strtok(0, "-"))
1381 subauths[numsubauths++] = atoi(p);
1382 DEBUG(4,("netlogon LINE %d %lx\n",__LINE__, q));
1389 qSSVAL(0); /* 2 undocumented bytes */
1391 qSSVAL(domlen*2); /* unicode domain len and maxlen */
1392 qSIVAL(4); /* domain buffer pointer */
1393 qSIVAL(2); /* domain sid pointer */
1394 qunistr(domainname);
1395 qSIVAL(numsubauths);
1397 qSCVAL(numsubauths);
1398 qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */
1399 qRSIVAL(identauth); /* next 4 bytes */
1400 for (i = 0; i < numsubauths; i++)
1402 qSIVAL(subauths[i]);
1405 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1408 case LSAENUMTRUSTDOM:
1409 DEBUG(1,("LSAENUMTRUSTDOM\n"));
1411 qSIVAL(0); /* enumeration context */
1412 qSIVAL(0); /* entries read */
1413 qSIVAL(0); /* trust information */
1414 endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len);
1418 DEBUG(1,("LSACLOSE\n"));
1425 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1429 DEBUG(1,("LSAOPENSECRET\n"));
1436 endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len);
1440 DEBUG(1,("LSAOPENSECRET\n"));
1442 policyhandle = q; q += 20;
1444 DEBUG(4,("lookupsid entries %d\n",nentries));
1445 q += (2+nentries) * 4; /* skip bufptrs */
1446 /* now we have nentries sids of the form:
1447 uint32 Subauthority count (SAC)
1449 char Subaurity count again
1450 char[6] Identifier authority
1451 [uint32 subauthority] * SAC
1453 for (nsids = 0; nsids < nentries; nsids++)
1455 DEBUG(4,("lookupsid q in %lx\n",q));
1457 DEBUG(4,("lookupsid numsubs %d\n",IVAL(q,0)));
1458 q += 4+1+1+6+IVAL(q,0)*4;
1459 DEBUG(4,("lookupsid q %lx\n",q));
1461 /* There's 16 bytes of something after all of that, don't know
1462 what it is though - incorrectly documented */
1464 DEBUG(4,("lookupsid line %d\n",__LINE__));
1465 /* formulate reply */
1467 qSIVAL(2); /* bufptr */
1468 qSIVAL(4); /* number of referenced domains
1469 - need one per each identifier authority in call */
1470 qSIVAL(2); /* dom bufptr */
1471 qSIVAL(32); /* max entries */
1472 qSIVAL(4); /* number of reference domains? */
1474 qunihdr(lp_workgroup()); /* reference domain */
1475 qSIVAL(2); /* sid bufptr */
1478 qSIVAL(2); /* sid bufptr */
1481 qSIVAL(2); /* sid bufptr */
1484 qSIVAL(2); /* sid bufptr */
1486 qunistr(lp_workgroup());
1487 DEBUG(4,("lookupsid line %d\n",__LINE__));
1489 strcpy(domsid,lp_domainsid());
1490 p = strtok(domsid+2,"-");
1492 identauth = atoi(strtok(0,"-"));
1494 while (p = strtok(0, "-"))
1495 subauths[numsubauths++] = atoi(p);
1496 qSIVAL(numsubauths);
1498 qSCVAL(numsubauths);
1499 qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */
1500 qRSIVAL(identauth); /* next 4 bytes */
1501 DEBUG(4,("lookupsid line %d\n",__LINE__));
1502 for (i = 0; i < numsubauths; i++)
1504 qSIVAL(subauths[i]);
1506 DEBUG(4,("lookupsid line %d\n",__LINE__));
1509 qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */
1510 DEBUG(4,("lookupsid line %d\n",__LINE__));
1513 qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */
1516 qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */
1519 qSIVAL(2); /* bufptr */
1521 DEBUG(4,("lookupsid line %d\n",__LINE__));
1522 for (i = 0; i < nentries; i++)
1524 qSSVAL(5); /* SID name use ?! */
1525 qSSVAL(0); /* undocumented */
1526 DEBUG(4,("lookupsid line %d\n",__LINE__));
1527 qunihdr(sidtostring(sids[i]));
1528 DEBUG(4,("lookupsid sidname %s\n",sidtostring(sids[i])));
1529 qSIVAL(0); /* domain index out of above reference domains */
1531 DEBUG(4,("lookupsid line %d\n",__LINE__));
1532 for (i = 0; i < nentries; i++)
1534 qunistr(sidtostring(sids[i]));
1536 qSIVAL(nentries); /* mapped count */
1537 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1540 case LSALOOKUPNAMES:
1541 DEBUG(1,("LSALOOKUPNAMES\n"));
1543 policyhandle = q; q += 20;
1545 DEBUG(4,("lookupnames entries %d\n",nentries));
1546 q += 4; /* skip second count */
1547 q += 8 * nentries; /* skip pointers */
1548 for (nnames = 0; nnames < nentries; nnames++)
1550 names[nnames] = q; /* set name string to unicode header */
1551 q += IVAL(q,0)*2; /* guessing here */
1553 /* There's a translated sids structure next but it looks fals */
1555 DEBUG(4,("lookupnames line %d\n",__LINE__));
1556 /* formulate reply */
1558 qSIVAL(2); /* bufptr */
1559 qSIVAL(4); /* number of referenced domains
1560 - need one per each identifier authority in call */
1561 qSIVAL(2); /* dom bufptr */
1562 qSIVAL(32); /* max entries */
1563 qSIVAL(4); /* number of reference domains? */
1565 qunihdr(lp_workgroup()); /* reference domain */
1566 qSIVAL(2); /* sid bufptr */
1569 qSIVAL(2); /* sid bufptr */
1572 qSIVAL(2); /* sid bufptr */
1575 qSIVAL(2); /* sid bufptr */
1577 qunistr(lp_workgroup());
1578 DEBUG(4,("lookupnames line %d\n",__LINE__));
1580 strcpy(domsid,lp_domainsid());
1581 p = strtok(domsid+2,"-");
1583 identauth = atoi(strtok(0,"-"));
1585 while (p = strtok(0, "-"))
1586 subauths[numsubauths++] = atoi(p);
1587 qSIVAL(numsubauths);
1589 qSCVAL(numsubauths);
1590 qRSSVAL(0); /* PAXX: FIX! first 2 bytes identifier authority */
1591 qRSIVAL(identauth); /* next 4 bytes */
1592 DEBUG(4,("lookupsid line %d\n",__LINE__));
1593 for (i = 0; i < numsubauths; i++)
1595 qSIVAL(subauths[i]);
1597 DEBUG(4,("lookupsid line %d\n",__LINE__));
1600 qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(1); /* S-1-1 */
1601 DEBUG(4,("lookupsid line %d\n",__LINE__));
1604 qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(5); /* S-1-5 */
1607 qSIVAL(0); qSCVAL(1); qSCVAL(0); qRSSVAL(0); qRSIVAL(3); /* S-1-3 */
1610 qSIVAL(2); /* bufptr */
1612 DEBUG(4,("lookupnames line %d\n",__LINE__));
1613 for (i = 0; i < nentries; i++)
1615 qSSVAL(5); /* SID name use 5 == well known sid, 1 == user sid see showacls */
1616 qSSVAL(5); /* undocumented */
1617 DEBUG(4,("lookupnames line %d\n",__LINE__));
1618 qSIVAL(nametorid(names[i]));
1619 DEBUG(4,("lookupnames nametorid %d\n",nametorid(names[i])));
1620 qSIVAL(0); /* domain index out of above reference domains */
1622 qSIVAL(nentries); /* mapped count */
1623 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1627 DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum));
1632 BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
1633 int mdrcnt,int mprcnt,
1634 char **rdata,char **rparam,
1635 int *rdata_len,int *rparam_len)
1644 int subauths[MAXSUBAUTHS];
1645 struct smb_passwd *smb_pass; /* To check if machine account exists */
1649 uint16 revision; /* Domain sid revision */
1655 uint16 secchanneltype;
1666 uint16 paramcontrol;
1669 uint16 usernamemaxlen;
1672 uchar *rc4lmowfpass;
1673 uchar *rc4ntowfpass;
1677 struct uinfo *userinfo;
1681 uchar ntowfpass[16];
1683 opnum = SVAL(data,22);
1685 pkttype = CVAL(data, 2);
1686 if (pkttype == 0x0b) /* RPC BIND */
1688 DEBUG(4,("netlogon rpc bind %x\n",pkttype));
1689 LsarpcTNP1(data,rdata,rdata_len);
1693 DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum));
1694 initrpcreply(data, *rdata);
1695 DEBUG(4,("netlogon LINE %d\n",__LINE__));
1699 DEBUG(1,("LSAREQCHAL\n"));
1702 logonsrv = q + 16; /* first 16 bytes, buffer ptr, + unicode lenghts */
1703 q = skip_unicode_string(logonsrv,1) + 12;
1704 q = align4(q, data);
1706 q = skip_unicode_string(unicomp,1);
1709 DEBUG(1,("logonsrv=%s unicomp=%s\n",
1713 dcauth[cnum].chal[0] = IVAL(q, 0);
1714 dcauth[cnum].chal[1] = IVAL(q, 4);
1715 dcauth[cnum].cred[0] = IVAL(q, 0); /* this looks weird (tridge) */
1716 dcauth[cnum].cred[1] = IVAL(q, 4);
1718 DEBUG(1,("NL: client challenge %08x %08x\n", dcauth[cnum].chal[0],dcauth[cnum].chal[1]));
1720 /* PAXX: set these to random values */
1721 dcauth[cnum].svrchal[0] = 0x11111111;
1722 dcauth[cnum].svrchal[1] = 0x22222222;
1723 dcauth[cnum].svrcred[0] = 0x11111111;
1724 dcauth[cnum].svrcred[1] = 0x22222222;
1725 strcpy(machacct,unistr(unicomp));
1726 strcat(machacct, "$");
1727 smb_pass = get_smbpwnam(machacct);
1729 memcpy(dcauth[cnum].md4pw, smb_pass->smb_nt_passwd, 16);
1732 /* No such machine account. Should error out here, but we'll
1733 print and carry on */
1734 DEBUG(1,("No account in domain at REQCHAL for %s\n", machacct));
1736 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",dcauth[cnum].md4pw[i]);
1737 DEBUG(1,("pass %s %s\n", machacct, foo));
1740 qSIVAL(dcauth[cnum].svrchal[0]);
1741 qSIVAL(dcauth[cnum].svrchal[1]);
1743 DEBUG(1,("NL: server challenge %08x %08x\n",
1744 dcauth[cnum].svrchal[0],dcauth[cnum].svrchal[1]));
1746 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1750 DEBUG(1,("LSAAUTH2\n"));
1754 q = skip_unicode_string(logonsrv,1)+12;
1755 q = align4(q, data);
1758 q = skip_unicode_string(accountname,1);
1759 secchanneltype = qSVAL;
1761 q = align4(q, data);
1763 dump_data(1,unicomp,32);
1764 q = skip_unicode_string(unicomp,1);
1767 q = align4(q, data);
1769 DEBUG(3,("AUTH2 logonsrv=%s accountname=%s unicomp=%s %lx %lx %lx\n",
1770 unistr(logonsrv), unistr(accountname), unistr(unicomp),
1771 rcvcred[0], rcvcred[1], negflags));
1773 DEBUG(1,("NL: recvcred %08x %08x negflags=%08x\n",
1774 rcvcred[0], rcvcred[1], negflags));
1776 checkcred(cnum, rcvcred[0], rcvcred[1], 0);
1778 makecred(cnum, 0, q);
1782 /* update stored client credentials */
1783 dcauth[cnum].cred[0] = dcauth[cnum].svrcred[0] = rcvcred[0];
1784 dcauth[cnum].cred[1] = dcauth[cnum].svrcred[1] = rcvcred[1];
1785 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
1789 DEBUG(1,("LSASVRPWSET\n"));
1793 q = skip_unicode_string(logonsrv,1)+12;
1794 q = align4(q, data);
1796 q = skip_unicode_string(accountname,1);
1797 secchanneltype = qSVAL;
1799 q = align4(q, data);
1801 q = skip_unicode_string(unicomp,1);
1806 DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n",
1807 unistr(logonsrv), unistr(accountname), unistr(unicomp)));
1809 checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
1810 DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags));
1813 DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n",
1814 unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass));
1816 /* PAXX: For the moment we'll reject these */
1817 /* TODO Need to set newpass in smbpasswd file for accountname */
1819 makecred(cnum, clnttime+1, q);
1821 qSIVAL(0); /* timestamp. Seems to be ignored */
1823 dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1;
1825 endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len);
1829 DEBUG(1,("LSASAMLOGON\n"));
1830 dump_data(1,data,128);
1833 DEBUG(1,("SMLOG %d\n", __LINE__));
1834 q = skip_unicode_string(logonsrv,1)+16;
1835 q = align4(q, data);
1837 q = skip_unicode_string(unicomp,1)+4;
1838 DEBUG(1,("SMLOG %d logonsrv=%s unicomp=%s\n",
1839 __LINE__, unistr(logonsrv), unistr(unicomp)));
1840 q = align4(q, data);
1842 DEBUG(1,("SMLOG %d\n", __LINE__));
1844 DEBUG(1,("SMLOG %d\n", __LINE__));
1846 checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
1848 rtncred[0] = qIVAL; /* all these are ignored */
1849 DEBUG(1,("SMLOG %d\n", __LINE__));
1853 DEBUG(1,("SMLOG %d\n", __LINE__));
1861 dommaxlen = qSVAL; q += 4;
1862 paramcontrol = qIVAL;
1863 logonid[0] = qIVAL; /* low part */
1864 logonid[1] = qIVAL; /* high part */
1866 usernamelen = qSVAL;
1868 DEBUG(1,("SMLOG %d\n", __LINE__));
1869 usernamemaxlen = qSVAL; q += 4;
1871 DEBUG(1,("usernamelen=%d maxlen=%d dommaxlen=%d\n",
1872 usernamelen, usernamemaxlen, dommaxlen));
1877 wsmaxlen = qSVAL; q += 4;
1878 rc4lmowfpass = q; q += 16;
1879 rc4ntowfpass = q; q += 16;
1881 q += 12; domain = q; q += dommaxlen + 12;
1882 q = align4(q, data);
1883 username = q; q += usernamemaxlen + 12;
1884 q = align4(q, data);
1886 DEBUG(1,("domain=%s username=%s ws=%s\n",
1887 unistr(domain), unistr(username),
1891 DEBUG(0,("unknown switch in SAMLOGON %d\n",
1894 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",username[i]);
1895 DEBUG(1,("userNAME %s [%s]\n", foo, username));
1896 DEBUG(1,("SMLOG %d\n", __LINE__));
1898 qSIVAL(0x16a4b4); /* magic buffer pointer ? */
1899 makecred(cnum, clnttime+1, q);
1900 dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1;
1902 qSIVAL(0); /* timestamp. client doesn't care */
1903 qSSVAL(3); /* switch value 3. May be others? */
1904 qSSVAL(0); /* undocumented */
1905 DEBUG(1,("SMLOG %d\n", __LINE__));
1907 memset(rc4key, 0, sizeof rc4key);
1908 SIVAL(rc4key, 0, dcauth[cnum].sesskey[0]);
1909 SIVAL(rc4key, 4, dcauth[cnum].sesskey[1]);
1910 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",rc4ntowfpass[i]);
1911 DEBUG(1,("rc4ntowf %s\n", foo));
1912 arcfour_init(&c, rc4key, sizeof rc4key);
1913 arcfour_encrypt(&c, ntowfpass, rc4ntowfpass, sizeof ntowfpass);
1914 for(i=0;i<16;i++) sprintf(foo+i*2,"%02x",ntowfpass[i]);
1915 DEBUG(1,("ntowf %s\n", foo));
1917 if(!(userinfo = getuserinfo(username, usernamelen, ntowfpass))) {
1918 qSIVAL(0); /* no buffer */
1919 qSCVAL(1); /* Authoratitive. Change if passthrough? */
1920 qSCVAL(0); /* pad for above boolean */
1921 qSSVAL(0); /* pad for above boolean */
1923 endrpcreply(data, *rdata, q-*rdata, 0xc0000064, rdata_len);
1927 qSIVAL(2); /* another magic bufptr? */
1928 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo));
1929 qSIVAL(userinfo->logontime[0]); qSIVAL(userinfo->logontime[1]);
1930 qSIVAL(userinfo->logofftime[0]); qSIVAL(userinfo->logofftime[1]);
1931 DEBUG(1,("SMLOG %d %lx\n", __LINE__, userinfo->passlastsettime[1]));
1932 qSIVAL(userinfo->kickofftime[0]); qSIVAL(userinfo->kickofftime[1]);
1933 qSIVAL(userinfo->passlastsettime[0]); qSIVAL(userinfo->passlastsettime[1]);
1934 qSIVAL(userinfo->passcanchgtime[0]); qSIVAL(userinfo->passcanchgtime[1]);
1935 qSIVAL(userinfo->passmustchgtime[0]); qSIVAL(userinfo->passmustchgtime[1]);
1936 DEBUG(1,("SMLOG %d %s\n", __LINE__, userinfo->effectivename));
1937 qunihdr(userinfo->effectivename);
1938 qunihdr(userinfo->fullname);
1939 DEBUG(1,("SMLOG %d\n", __LINE__));
1940 qunihdr(userinfo->logonscript);
1941 qunihdr(userinfo->profilepath);
1942 qunihdr(userinfo->homedirectory);
1943 qunihdr(userinfo->homedirectorydrive);
1944 DEBUG(1,("SMLOG %d\n", __LINE__));
1945 qSSVAL(userinfo->logoncount);
1946 qSSVAL(userinfo->badpwcount);
1947 qSIVAL(userinfo->uid);
1948 qSIVAL(userinfo->gid);
1949 DEBUG(1,("SMLOG %d\n", __LINE__));
1950 qSIVAL(userinfo->ngroups);
1951 qSIVAL(8); /* ptr to groups */
1952 qSIVAL(userinfo->userflags);
1953 DEBUG(1,("SMLOG %d\n", __LINE__));
1954 qSIVAL(0); qSIVAL(0); qSIVAL(0); qSIVAL(0); /* unused user session key */
1955 qunihdr(userinfo->logonserver);
1956 qunihdr(userinfo->logondomain);
1957 DEBUG(1,("SMLOG %d\n", __LINE__));
1958 qSIVAL(2); /* logon domain id ptr */
1959 DEBUG(1,("SMLOG %d\n", __LINE__));
1960 memset(q,0,40); q += 40; /* expansion room */
1961 DEBUG(1,("SMLOG %d\n", __LINE__));
1962 qSIVAL(userinfo->nsids);
1963 DEBUG(1,("SMLOG %d\n", __LINE__));
1964 qSIVAL(0); /* ptr to sids and values */
1965 DEBUG(1,("SMLOG %d\n", __LINE__));
1966 qunistr(userinfo->effectivename);
1967 DEBUG(1,("SMLOG %d\n", __LINE__));
1968 qunistr(userinfo->fullname);
1969 DEBUG(1,("SMLOG %d\n", __LINE__));
1970 qunistr(userinfo->logonscript);
1971 DEBUG(1,("SMLOG %d\n", __LINE__));
1972 qunistr(userinfo->profilepath);
1973 qunistr(userinfo->homedirectory);
1974 qunistr(userinfo->homedirectorydrive);
1975 DEBUG(1,("SMLOG %d\n", __LINE__));
1976 qSIVAL(userinfo->ngroups);
1977 for (i = 0; i < userinfo->ngroups; i++)
1979 qSIVAL(userinfo->groups[i].gid);
1980 qSIVAL(userinfo->groups[i].attr);
1982 qunistr(userinfo->logonserver);
1983 qunistr(userinfo->logondomain);
1984 for (i = 0; i < userinfo->nsids; i++)
1986 /* put the extra sids: PAXX: TODO */
1988 /* Assumption. This is the only domain, sending our SID */
1989 /* PAXX: may want to do passthrough later */
1990 strcpy(domsid,lp_domainsid());
1991 DEBUG(4,("netlogon LINE %d %lx %s\n",__LINE__, q, domsid));
1992 /* assume, but should check, that domsid starts "S-" */
1993 p = strtok(domsid+2,"-");
1995 DEBUG(4,("netlogon LINE %d %lx %s rev %d\n",__LINE__, q, p, revision));
1996 identauth = atoi(strtok(0,"-"));
1997 DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth));
1999 while (p = strtok(0, "-"))
2000 subauths[numsubauths++] = atoi(p);
2001 qSIVAL(numsubauths);
2003 qSCVAL(numsubauths);
2004 qRSSVAL(0); /* PAXX: FIX. first 2 bytes identifier authority */
2005 qRSIVAL(identauth); /* next 4 bytes */
2006 DEBUG(1,("SMLOG %d\n", __LINE__));
2007 for (i = 0; i < numsubauths; i++)
2009 qSIVAL(subauths[i]);
2011 qSCVAL(1); /* Authoratitive. Change if passthrough? */
2012 qSCVAL(0); /* pad for above boolean */
2013 qSSVAL(0); /* pad for above boolean */
2015 endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
2019 DEBUG(1,("LSASAMLOGOFF\n"));
2022 DEBUG(1,("SAMLOGOFF %d\n", __LINE__));
2023 unicomp = skip_unicode_string(logonsrv,1)+16;
2024 if (strlen(unistr(logonsrv)) % 2 == 0)
2026 DEBUG(1,("SMLOG %d\n", __LINE__));
2027 q = skip_unicode_string(unicomp,1)+4;
2028 if (strlen(unistr(unicomp)) % 2 == 0)
2030 DEBUG(1,("SMLOG %d\n", __LINE__));
2032 DEBUG(1,("SMLOG %d\n", __LINE__));
2034 DEBUG(1,("SMLOG %d\n", __LINE__));
2036 checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
2038 rtncred[0] = qIVAL; /* all these are ignored */
2039 DEBUG(1,("SMLOG %d\n", __LINE__));
2043 DEBUG(1,("SMLOG %d\n", __LINE__));
2050 dommaxlen = qSVAL; q += 4;
2051 paramcontrol = qIVAL;
2052 logonid[0] = qIVAL; /* low part */
2053 logonid[1] = qIVAL; /* high part */
2054 usernamelen = qSVAL;
2055 DEBUG(1,("SMLOG %d\n", __LINE__));
2056 usernamemaxlen = qSVAL; q += 4;
2058 wsmaxlen = qSVAL; q += 4;
2059 rc4lmowfpass = q; q += 16;
2060 rc4ntowfpass = q; q += 16;
2061 q += 12; domain = q; q += dommaxlen + 12;
2062 if ((domlen/2) % 2 != 0) q += 2;
2063 username = q; q += usernamemaxlen + 12; /* PAXX: HACK */
2064 if ((usernamelen/2) % 2 != 0) q += 2;
2067 default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval));
2069 DEBUG(1,("SAMLOGOFF %s\n", unistr(username)));
2071 DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
2076 static void checkcred(int cnum, uint32 cred0, uint32 cred1, uint32 time)
2085 SIVAL(netdata, 0, dcauth[cnum].cred[0]+time);
2086 SIVAL(netdata, 4, dcauth[cnum].cred[1]);
2087 SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]);
2088 SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]);
2089 E1(netsesskey,netdata,icv);
2090 memset(key2, 0, sizeof key2);
2091 key2[0] = netsesskey[7];
2092 E1(key2, icv, calccred);
2093 if (IVAL(calccred,0) != cred0 ||
2094 IVAL(calccred,4) != cred1)
2096 DEBUG(1,("Incorrect client credential received cred %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n",
2098 dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1],
2099 dcauth[cnum].cred[0], dcauth[cnum].cred[1],
2100 IVAL(calccred,0), IVAL(calccred,4)));
2101 /* PAXX: do something about it! */
2103 DEBUG(4,("Correct client credential received chal %lx %lx time %lx sk %lx %lx cred %lx %lx expcred %lx %lx\n",
2105 dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1],
2106 dcauth[cnum].cred[0], dcauth[cnum].cred[1],
2107 IVAL(calccred,0), IVAL(calccred,4)));
2110 static void makecred(int cnum, uint32 time, char *calccred)
2118 SIVAL(netdata, 0, dcauth[cnum].svrcred[0]+time);
2119 SIVAL(netdata, 4, dcauth[cnum].svrcred[1]);
2120 SIVAL(netsesskey, 0, dcauth[cnum].sesskey[0]);
2121 SIVAL(netsesskey, 4, dcauth[cnum].sesskey[1]);
2122 E1(netsesskey,netdata,icv);
2123 memset(key2, 0, sizeof key2);
2124 key2[0] = netsesskey[7];
2125 E1(key2, icv, calccred);
2126 DEBUG(4,("Server credential: chal %lx %lx sk %lx %lx cred %lx %lx calc %lx %lx\n",
2127 dcauth[cnum].svrchal[0], dcauth[cnum].svrchal[1],
2128 dcauth[cnum].sesskey[0], dcauth[cnum].sesskey[1],
2129 dcauth[cnum].svrcred[0], dcauth[cnum].svrcred[1],
2130 IVAL(calccred, 0), IVAL(calccred, 4)));
2133 static void setsesskey(int cnum)
2140 sum[0] = dcauth[cnum].chal[0] + dcauth[cnum].svrchal[0];
2141 sum[1] = dcauth[cnum].chal[1] + dcauth[cnum].svrchal[1];
2142 SIVAL(netsum,0,sum[0]);
2143 SIVAL(netsum,4,sum[1]);
2144 E1(dcauth[cnum].md4pw,netsum,icv);
2145 E1(dcauth[cnum].md4pw+9,icv,netsesskey);
2146 dcauth[cnum].sesskey[0] = IVAL(netsesskey,0);
2147 dcauth[cnum].sesskey[1] = IVAL(netsesskey,4);
2149 DEBUG(1,("NL: session key %08x %08x\n",
2150 dcauth[cnum].sesskey[0],
2151 dcauth[cnum].sesskey[1]));
2154 static struct uinfo *getuserinfo(char *user, int len, char *ntowfpass)
2156 static struct uinfo u;
2157 static pstring fullnm;
2158 static pstring ascuser;
2159 extern pstring myname;
2160 static pstring stme;
2161 static pstring stdom;
2162 struct smb_passwd *smb_pass;
2164 strcpy(ascuser,unistr(user));
2165 ascuser[len/2] = 0; /* PAXX: FIXMEFIXMEFIXME */
2166 DEBUG(1,("GETUSER username :%s: len=%d\n",ascuser, len));
2168 smb_pass = get_smbpwnam(ascuser);
2171 DEBUG(1,("GETU %d\n", __LINE__));
2172 if (memcmp(ntowfpass, smb_pass->smb_nt_passwd, 16)) {
2173 DEBUG(1,("pass mismatch:\n"));
2174 dump_data(1,ntowfpass,16);
2175 dump_data(1,smb_pass->smb_nt_passwd,16);
2179 DEBUG(1,("GETU %d\n", __LINE__));
2180 u.logontime[0] = 0xffffffff; u.logontime[1] = 0x7fffffff;
2181 u.logofftime[0] = 0xffffffff; u.logofftime[1] = 0x7fffffff;
2182 u.kickofftime[0] = 0xffffffff; u.kickofftime[1] = 0x7fffffff;
2183 DEBUG(1,("GETU %d\n", __LINE__));
2184 u.passlastsettime[0] = 0xffffffff; u.passlastsettime[1] = 0x7fffffff;
2185 u.passcanchgtime[0] = 0xffffffff; u.passcanchgtime[1] = 0x7fffffff;
2186 u.passmustchgtime[0] = 0xffffffff; u.passmustchgtime[1] = 0x7fffffff;
2187 DEBUG(1,("GETU %d\n", __LINE__));
2188 u.effectivename = ascuser;
2189 strcpy(fullnm, "Full name of ");
2190 strcat(fullnm, ascuser);
2191 DEBUG(1,("GETU %d\n", __LINE__));
2192 u.fullname = fullnm;
2193 u.logonscript = "foologin.cmd";
2194 u.profilepath = "prof";
2195 u.homedirectory = "foohomes";
2196 DEBUG(1,("GETU %d\n", __LINE__));
2197 u.homedirectorydrive = "a:";
2201 DEBUG(1,("GETU %d\n", __LINE__));
2204 u.groups = (struct groupinfo *)(malloc(sizeof (struct groupinfo) * 2));
2205 u.groups[0].gid = 776;
2206 DEBUG(1,("GETU %d\n", __LINE__));
2207 u.groups[0].attr = 0x7;
2208 u.groups[1].gid = 776;
2209 u.groups[1].attr = 0x7;
2211 u.logonserver = stme;
2212 get_myname(myname,NULL);
2213 strcpy(stme, myname);
2215 DEBUG(1,("LS %s\n", u.logonserver));
2216 u.logondomain = stdom;
2217 strcpy(stdom, lp_workgroup());
2219 DEBUG(1,("DOM %s\n", u.logondomain));
2222 DEBUG(1,("GETU %d\n", __LINE__));
2227 #endif /* NTDOMAIN */